Swift sorts an array with strings and numbers

I have an array of strings,

let array = [ "10", "1", "101", "NA", "100", "20", "210", "200", "NA", "7" ] 

I would like the output sorted in ascending order,

 let sorted = [ "1", "7", "10", "20", "100", "101", "200", "210", "NA", "NA" ] 

I tried using a sorted command, but it does not work when more than 2 digits are encountered, for example: 100, 101, 200, etc.

 array.sorted { $0? < $1? } 

What would be an easy way to get this?

+18
source share
1 answer

editing / updating: Xcode 10.2.x • Swift 5

You can use String method localizedStandardCompare

 let array = [ "10", "1", "101", "NA", "100", "20", "210", "200", "NA", "7" ] let sorted = array.sorted {$0.localizedStandardCompare($1) == .orderedAscending} print(sorted) // ["1", "7", "10", "20", "100", "101", "200", "210", "NA", "NA"] 

or using the sort(by:) method for the MutableCollection collection:

 var array = [ "10", "1", "101", "NA", "100", "20", "210", "200", "NA", "7" ] array.sort {$0.localizedStandardCompare($1) == .orderedAscending} print(array) // ["1", "7", "10", "20", "100", "101", "200", "210", "NA", "NA"] 

You can also implement your own localized standard sorting method that extends the collection:

 extension Collection where Element: StringProtocol { public func localizedStandardSorted(_ result: ComparisonResult) -> [Element] { return sorted { $0.localizedStandardCompare($1) == result } } } 

 let array = [ "10", "1", "101", "NA", "100", "20", "210", "200", "NA", "7" ] let sorted = array.localizedStandardSorted(.orderedAscending) print(sorted) // ["1", "7", "10", "20", "100", "101", "200", "210", "NA", "NA"] 

The mutation method, as well as the MutableCollection extension:

 extension MutableCollection where Element: StringProtocol, Self: RandomAccessCollection { public mutating func localizedStandardSort(_ result: ComparisonResult) { sort { $0.localizedStandardCompare($1) == result } } } 

 var array = [ "10", "1", "101", "NA", "100", "20", "210", "200", "NA", "7" ] array.localizedStandardSort(.orderedAscending) print(array) // ["1", "7", "10", "20", "100", "101", "200", "210", "NA", "NA"] 

If you need to sort the array numerically, you can use the string comparison method by setting the options parameter to .numeric :

 public extension Collection where Element: StringProtocol { func sortedNumerically(_ result: ComparisonResult) -> [Element] { return sorted { $0.compare($1, options: .numeric) == result } } } public extension MutableCollection where Element: StringProtocol, Self: RandomAccessCollection { mutating func sortNumerically(_ result: ComparisonResult) { sort { $0.compare($1, options: .numeric) == result } } } 

 var numbers = ["1.5","0.5","1"] let sorted = numbers.sortedNumerically(.orderedAscending) print(sorted) // ["0.5", "1", "1.5"] print(numbers) // ["1.5","0.5","1"] // mutating the original collection numbers.sortNumerically(.orderedDescending) print(numbers) // "["1.5", "1", "0.5"]\n" 
+47
source

All Articles