简体   繁体   中英

Sorting array alphabetically with number

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]

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 .

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"]

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]

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.)

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

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]|;         
}];

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

let sortedArray = myArray.sorted(by: { x, y in return x.field.name.compare(y.field.name, options: .numeric, range: nil, locale: nil) == .orderedAscending })

You can use a loop equal to length of the array, ie 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;
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM