2015-10-12 2 views
0

У меня есть Array, содержащие значения, как 7-4.json, 87-1.json и 102-4.json и хотите отсортировать его (по возрастанию). Я использовал следующий код:Swift: Как отсортировать массив <String>

var fileNames = ["7-4.json", "87-1.json", "102-4.json"] 
fileNames = fileNames.sort{ $0 < $1 } 
print(fileNames) 

, что приводит к:

["102-4.json", "7-4.json", "87-1.json"] 

Так он не работал, как я аспектирован. Как я могу сортировать его как 7-4, 87-1, 102-4?

+1

Вы будете нуждаться в пользовательскую функцию сортировки для таких ситуаций, чтобы иметь дело с конкретным форматом строки. – erdekhayser

+1

Просто чтобы вы знали, почему он это делает: он сортирует их как строки, а не числа, и поэтому сортирует по символу по характеру. –

+0

'let array2 = array.sort {$ 0.compare ($ 1, options: .NumericSearch) == .OrderedAscending}' сделал работу для меня – ixany

ответ

4

Здесь вы идете:

var fileNames = ["7-4.json", "87-1.json", "102-4.json"] 

func sortWithCustomFormat(first: String, second: String) -> Bool{ 
    func extract(value: String) -> (Int, Int){ 
     return (Int(value.componentsSeparatedByString("-").first!)!, Int(value.componentsSeparatedByString("-").last!.componentsSeparatedByString(".").first!)!) 
    } 
    let firstNumber = extract(first) 
    let secondNumber = extract(second) 
    if firstNumber.0 != secondNumber.0 { return firstNumber.0 < secondNumber.0 } 
    return firstNumber.1 < secondNumber.1 
} 

fileNames.sort(sortWithCustomFormat) 

Функция sortWithCustomFormat имеет функцию extract, которая принимает введенную строку и извлекает первый и второй номера от него. Затем вы сравниваете первые числа. Если они равны, то вы сравниваете второе число.

+0

Я думаю, что мы все придумали простые варианты того же решения, но я не видя, что ваша работа над вторым полем на игровой площадке ... – Grimxn

+0

@Grimxn Можете ли вы дать набор имен файлов, которые не работают, поэтому я могу видеть, что не так? – erdekhayser

+0

'fileNames = [" 7-4.json "," 87-1.json "," 102-4.json "," 102-1.json "]' похоже, не сортирует последние два на моей игровой площадке ... – Grimxn

0
var fileNames = ["87-1.json", "7-4.json", "87-3.json", "102-4.json"] 
fileNames = fileNames.sort({ (s1, s2) -> Bool in 

    let f1 = s1.stringByReplacingOccurrencesOfString(".json", withString: "") 
    let f2 = s2.stringByReplacingOccurrencesOfString(".json", withString: "") 

    let arr1 = f1.componentsSeparatedByString("-") 
    let arr2 = f2.componentsSeparatedByString("-") 


    var int1 = Int(arr1[0]) 
    var int2 = Int(arr2[0]) 

    if int1 < int2 { 
     return true 
    } 
    else if int1 > int2 { 
     return false 
    } 
    else { 
     int1 = Int(arr1[1]) 
     int2 = Int(arr2[1]) 
     if int1 < int2 { 
      return true 
     } 
     else if int1 > int2 { 
      return false 
     } 
     else { 
      return true 
     } 
    } 
}); 
print(fileNames) 
0

Попробуйте это ...

var fileNames = ["87-1.json", "7-4.json", "102-4.json"] 
// Modded OP's order to actually test sort 
var sorted = fileNames.sort{ $0 < $1 } 
print(sorted) // ["102-4.json", "7-4.json", "87-1.json"] 
// Not sorted as OP "required", as they are string sorted, not number sorted 

// Very simplistic solution 
sorted = fileNames.sort { ($0 as NSString).integerValue < ($1 as NSString).integerValue} 
print(sorted) // As OP requires, but... 

// It won't sort on his count field - add a failing case... 
fileNames = ["7-4.json", "87-1.json", "102-4.json", "102-1.json"] 
sorted = fileNames.sort { ($0 as NSString).integerValue < ($1 as NSString).integerValue} 
print(sorted) // ["7-4.json", "87-1.json", "102-4.json", "102-1.son"] 
// WRONG! 

// Define a simple function that parses his strings into tuples. 
// This assumes that the Strings are valid, and fails safe if not. 
// If you want more validation, add it yourself! 
func myParse(s: String) -> (Int, Int) { 
    let c = s.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "-.")) 
    switch c.count { 
    case 0: 
     print("Careful Will Robinson!") 
     return (0, 0) 
    case 1: 
     print("Careful Will Robinson!") 
     return ((c[0] as NSString).integerValue, 0) 
    default: 
     return ((c[0] as NSString).integerValue, (c[1] as NSString).integerValue) 
    } 
} 

let test = fileNames.map { myParse($0) } 
print("\(test)") // Test execution of function 

sorted = fileNames.sort { (s1: String, s2: String) -> Bool in 
    let t1 = myParse(s1) 
    let t2 = myParse(s2) 
    if t1.0 == t2.0 { 
     return t1.1 < t2.1 
    } else { 
     return t1.0 < t2.0 
    } 
} 
print(sorted) // As required ["7-4.json", "87-1.json", "102-1.json", "102-4.json"] 
Смежные вопросы