2

I am getting an Array from server and I store it in NSMutableArray. Now the issue is that the Array is not sorted. For eg. array = ["A","B","None","C","D"]. I want to sort it and place the "None" element at last. i.e ["A","B","C","D","None"]. Tried swapping but was unable to match the condition, as the array may increase in future. Check my code below which is not working as expected.

if array.containsObject( "None" ){
        print("\(array.indexOfObject("None"))")
        let noneIndex = array.indexOfObject("None")
        print(noneIndex)
        array.removeObject(noneIndex)
        print("Remove Array:-\(array)")
        array.insertObject(noneIndex, atIndex: (array.lastObject?.index)!)
        print("Sorted Array:-\(array)")
    }
3
  • 1
    Is there any reason why you don't use the provided sort() or sorted() methods? Commented Dec 15, 2016 at 7:49
  • You just need array.addobject("None") Commented Dec 15, 2016 at 7:53
  • 2
    Why NSMutableArray and not a Swift array [String] ? Commented Dec 15, 2016 at 7:58

4 Answers 4

2

Maybe I'm misunderstanding what it is that you need to do, but you could use sorted() on your array if you just want to sort it alphabetically.

You could also use filter to remove "None" from your array, sort it, and then append "None" as the last element

For instance, if you have

let elements = ["Alpha", "Bold", "None", "charlie", "Delta", "echo", "zebra", "k"]

You could start out by filtering it:

let filteredElements = elements.filter { $0.uppercased() != "NONE"}

Sort the filtered elements:

var sortedElements = filteredElements.sorted { $0.uppercased() < $1.uppercased()}

Append "None"

sortedElements.append("None") // ["Alpha", "Bold", "charlie", "Delta", "echo", "k", "zebra", "None"]

And be done.

Here it is combined:

let lastElement = "None"
let elements = ["Alpha", "Bold", "None", "charlie", "Delta", "echo", "zebra", "k"]
var sortedElements = elements.filter({$0.uppercased() != lastElement.uppercased()}).sorted(by: {$0.uppercased() < $1.uppercased()})
sortedElements.append(lastElement)

Hope that helps you.

Sign up to request clarification or add additional context in comments.

10 Comments

Its not just alphabets , it can be anything , like words, . Condition is "None" should be last everytime.
@iDeveloper, in sorted closure add condition that makes "None" always greatest value.
@pbodsk this is not working, it says, Value of type 'Elememt'(Aka 'AnyObject') has no member 'uppercased'
Hmm, OK, that must be because your array is defined as containing AnyObject objects instead of Strings. How is your array defined?
And as @jpetric says in a comment to his answer, you should consider using a Swift array instead of NSMutableArray. You get the filter, map and sorted methods amongst other goodies :)
|
1
var array = ["A", "B", "None", "C", "D"]
if let noneIndex = array.index(of: "None") {
    array.remove(at: noneIndex)
    array.append("None")
}
print(array)

1 Comment

Note that you don't need the check if array.contains() if you write if let noneIndex = array.indexOf("None") {
1

This should move None at the end of the array, and sort the other elements:

let ["A", "B", "None", "C", "D"]
array.sorted { $1 == "None" || $0 < $1 } // ["A", "B", "C", "D", "None"]

This simply takes benefits of the by argument that can be passed to the sort/sorted method from Array.

Edit @MartinR had a very strong point regarding the comparison predicate from this answer, which indeed doesn't offer a strong weak ordering. Sorting the array with a correct predicate would be along the lines of:

array.sorted { $0 == "None" ? false : $1 == "None" ? true : $0 < $1 }

5 Comments

@MartinR thanks for the observation, corrected the code
That might work, but now the comparator is not a "strict weak ordering" as required: "None" < "None"
@MartinR, correct, instances of "None" will be moved around due to the fact that "None" < "None". We can be pedantic and address this, we gain a little speed, however with the cost of increasing the complexity of the closure.
I don't think this is unnecessary pedantry. The sorted methods requires a strict weak ordering. If that prerequisite is not satisfied the behaviour is undefined.
@MartinR, hmm... I missed the strict weak ordering part from the API docs, thanks for bringing that up. I updated the answer, hopefully now is a correct one :)
0

This will work:

// starting test array
let array = ["B", "None", "C","P","None","A", "Q"]
var sorted = array.sorted { (str1, str2) -> Bool in
    return str1 < str2
}

sorted.forEach { str in
    if str == "None" {
        if let idx = sorted.index(of: str) {
            sorted.remove(at: idx)
            sorted.append(str)
        }
    }
}

// Sorted array is now ["A", "B", "C", "P", "Q", "None", "None"]

5 Comments

I would suggest using Swift's array. It will be better in the long run.
Sorted is not available in swit 3.
You sure? Because I tried the example in Playground with Swift 3. If you copy this whole example in Playground it should work.
XCode 8.1 Swift 3
There should be array.sorted method in swift 3.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.