L. Verardo L. Verardo - 2 years ago 121
Swift Question

How to sort an array with string in it in Swift?

I have these arrays :

ArrayEntr = ["Hello (40 km)", "Salut (20 km)", "Bonjour (30 km)", "Hi (35 km)"]
ArraySorted = ["20", "30", "35", "40"]

I would like to replace ArrayEntr in the same order as ArraySorted. In fact, I would like to sort ArrayEntr ascendantly with the number at the end

I've tried a few loops but I can't get it working as I want to.

Thank's a lot !

Answer Source

If you're getting this array from an external source which doesn't provide the numerical information along with the strings, you'll have to extract the numbers from them yourself. Of course if you had the numerical information to begin with at some point, you should've hung onto it as @matt says.

One way of getting the numerical information back out of your strings would be using forEach on your array, followed by using componentsSeparatedByCharactersInSet on each element in order to divide the string up into the sub-strings that contain numbers. We can then filter out the empty components, and get the first numerical component as an optional double. We can then add this number to a new array of (String, Double) tuples. For example:

let strings = ["foobar", "Hello (45.5 km)", "Salut (20.45 km)", "Bonjour (30 km)", "Hi (35 km)"]

// the inverted set of characters that we want to define as a number
let allowedCharacters = NSCharacterSet(charactersInString: "0123456789.").invertedSet

// new array of string and double tuples
var stringsWithNumbers = [(string:String, number:Double)]()

// loop though strings
strings.forEach { str in

    // get the components seperated by the filtered out characters, filtering out empty strings – then casting to a double
    if let number = str.componentsSeparatedByCharactersInSet(allowedCharacters).filter({!$0.isEmpty}).first.flatMap({Double($0)}) {

        // if it's a valid double, add the element to the array
        stringsWithNumbers.append((str, number))

print(stringsWithNumbers) // [("Hello (45.5 km)", 45.5), ("Salut (20.45 km)", 20.449999999999999), ("Bonjour (30 km)", 30.0), ("Hi (35 km)", 35.0)]

This will also filter out strings that didn't contain numbers to begin with.

You can then sort this array by using the sort function. For example:

let sorted = stringsWithNumbers.sort {$0.number < $1.number}.map{$0.string} // sort, then ditch the distance information
print(sorted) // ["Salut (20.45 km)", "Bonjour (30 km)", "Hi (35 km)", "Hello (45.5 km)"]

If you wish to keep the tuples of strings with doubles, you can remove the map at the end.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download