I want to sort an alphanumeric, but numbers should come at end instead of beginning. for instance
let array = [\"1\", \"a\", \"b\", \"z\", \"3\", \"!\"]
let sor
Here's a solution that works for your case :
The expected result is :
Here's a way to do it.
// Works with both arrays
var array = ["1", "b", "a", "z", "3", "!"]
//var array = ["1", "b", "A", "Z", "3", "!"]
func isLetter(char: String) -> Bool {
return ("a"..."z").contains(char) || ("A"..."Z").contains(char)
}
func isNumber(char: String) -> Bool {
return Int(char) != nil
}
let letters = array.filter(isLetter).sort{$0.lowercaseString < $1.lowercaseString}
let numbers = array.filter(isNumber).sort{Int($0) < Int($1)}
let others = Array(Set(array).subtract(letters).subtract(numbers)).sort{$0 < $1}
let sortedArray = letters + numbers + others
The first array would be
["a", "b", "z", "1", "3", "!"]
The second would be
["A", "b", "Z", "1", "3", "!"]
It does what you want. Include unit tests and wrap that inside a method and you're good to go. Buuuut, it's not "clean" at all.
Assume that you want to receive "numbers should come at end instead of beginning", without watching your example with unexpected "!" sorting. Then you can do this:
let array = ["1", "a", "b", "z", "3", "!"]
let sortedArray = array.sort { (firstObject, secondObject) -> Bool in
let firstIsNumber = firstObject.rangeOfCharacterFromSet(NSCharacterSet.decimalDigitCharacterSet())?.count > 0
let secondIsNumber = secondObject.rangeOfCharacterFromSet(NSCharacterSet.decimalDigitCharacterSet())?.count > 0
if firstIsNumber != secondIsNumber {return secondIsNumber}
return firstObject < secondObject
}
print(sortedArray)
//["!", "a", "b", "z", "1", "3"]