Home » Swift » Sorting array alphabetically with number

Sorting array alphabetically with number

Posted by: admin November 30, 2017 Leave a comment

Questions:
myArray = [Step 6, Step 12, Step 5, Step 14, Step 4, Step 11, Step 16, Step 9, 
Step 3, Step 13, Step 8, Step 2, Step 10, Step 7, Step 1, Step 15]

How can I sort this array above in this way?

[Step 1, Step 2, Step 3, Step 4, ....]

I used this function in swift sort(&myArray,{ $0 < $1 }) but it was sorted this way

[Step 1, Step 10, Step 11, Step 12, Step 13, Step 14, Step 15, Step 16, Step 2, 
 Step 3, Step 4, Step 5, Step 6, Step 7, Step 8, Step 9]
Answers:

Another variant is to use
localizedStandardCompare:. From the documentation:

This method should be used whenever file names or other strings are
presented in lists and tables where Finder-like sorting is
appropriate.

This will sort the strings as appropriate for the current locale.
Example:

let myArray = ["Step 6", "Step 12", "Step 10"]

let ans = sorted(myArray,{ (s1, s2) in 
    return s1.localizedStandardCompare(s2) == NSComparisonResult.OrderedAscending
})

println(ans)
// [Step 6, Step 10, Step 12]

Update: The above answer is quite old and for Swift 1.2. A Swift 3 version is (thanks to @Ahmad):

let ans = myArray.sorted {
    (s1, s2) -> Bool in return s1.localizedStandardCompare(s2) == .orderedAscending
}

For a different approach see https://stackoverflow.com/a/31209763/1187415,
translated to Swift 3 at https://stackoverflow.com/a/39748677/1187415.

Questions:
Answers:

In Swift 2:

import Foundation

let myArray = ["Step 6", "Step 12", "Step 10"]

extension String {
  func extractIntFromEnd() -> Int? {
    return self.componentsSeparatedByString(" ").last.flatMap{Int($0)}
  }
}

let ans = myArray.sort {
  (first, second) in
  first.extractIntFromEnd() < second.extractIntFromEnd()
}

In Swift 1:

let myArray = ["Step 6", "Step 12", "Step 10"]

extension String {
  func extractIntFromEnd() -> Int? {
    return self.componentsSeparatedByString(" ").last.flatMap{$0.toInt()}
  }
}

let ans = myArray.sorted {
  (first, second) in
  first.extractIntFromEnd() < second.extractIntFromEnd()
}

In both, this array:

let myArray = [
  "Step 6" ,
  "Step 12",
  "Step 5" ,
  "Step 14",
  "Step 4" ,
  "Step 11",
  "Step 16",
  "Step 9" ,
  "Step 3" ,
  "Step 13",
  "Step 8" ,
  "Step 2" ,
  "Step 10",
  "Step 7" ,
  "Step 1" ,
  "Step 15"
]

Will give you this answer:

["Step 1", "Step 2", "Step 3", "Step 4", "Step 5", "Step 6", "Step 7", "Step 8", "Step 9", "Step 10", "Step 11", "Step 12", "Step 13", "Step 14", "Step 15", "Step 16"]

(In the Swift 2.0 version, you should be able to do last.flatMap(Int.init), but it’s not working for me for some reason. Even something like ["1", "2"].flatMap(Int.init) is crashing my playground. Looks like a bug.)

Questions:
Answers:

NSString has a rich set of methods for comparing strings. You can use the method compare:options:.

You’ll want the NSNumericSearch option. If you read the description of that option, it says:

Numbers within strings are compared using numeric value, that is,
Name2.txt < Name7.txt < Name25.txt.

So you could write a Swift sort line that does what you want using that function.

Something like this:

let myArray = ["Step 6", "Step 12", "Step 10"]

let ans = myArray.sorted {
    (first, second) in
    first.compare(second, options: .NumericSearch) == NSComparisonResult.OrderedAscending
}

println(ans)
// [Step 6, Step 10, Step 12]

Questions:
Answers:

The Swift 3 version of Duncan C’s answer is

let myArray = ["Step 6", "Step 12", "Step 10"]

let sortedArray = myArray.sorted {
    $0.compare($1, options: .numeric) == .orderedAscending
}

print(sortedArray) // ["Step 6", "Step 10", "Step 12"]

Or, if you want to sort the array in-place:

var myArray = ["Step 6", "Step 12", "Step 10"]

myArray.sort {
    $0.compare($1, options: .numeric) == .orderedAscending
}

print(myArray) // ["Step 6", "Step 10", "Step 12"]

Questions:
Answers:

Sorting in Swift 2.0 Demo link, change of syntax from “sorted(myArray,{})” to “myArray.sort({})”. Extensible Protocol.

let myArray = ["Step 6", "Step 12", "Step 10"]
let sortedArray = myArray.sort({ x, y in
    return x.localizedStandardCompare(y) == NSComparisonResult.OrderedAscending
})

dump(sortedArray)

Swift 1.2 Demo

Questions:
Answers:
NSArray *assorted = [@"1 2 3 9 ; : 구 , 결 A B C Z ! á" componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *sorted = [assorted sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    /* NSOrderedAscending, NSOrderedSame, NSOrderedDescending */
    BOOL isPunct1 = [[NSCharacterSet punctuationCharacterSet] characterIsMember:[(NSString*)obj1 characterAtIndex:0]];
    BOOL isPunct2 = [[NSCharacterSet punctuationCharacterSet] characterIsMember:[(NSString*)obj2 characterAtIndex:0]];
    if (isPunct1 && !isPunct2) {
        return NSOrderedAscending;
    } else if (!isPunct1 && isPunct2) {
        return NSOrderedDescending;
    }
    return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch|NSNumericSearch]|;         
}];

Questions:
Answers:

You can use a loop equal to length of the array, i.e. for(i=0;i<myArray.length;i++) and then can use a variable to sort them in order like:

for (int i = 0; i < myArray.length; i++) 
{
  for (int j = i + 1; j < n; j++) 
  {
    if (a[i] > a[j]) 
    {
      temp = a[i];
      a[i] = a[j];
      a[j] = temp;
    }
  }
}