2015-08-13 7 views
1

У меня проблема с моим алгоритмом сортировки.Swift sort NSArray

Мои NSArray (здесь vcd.signals.key) содержит значения строк, например:

"x [0]", "x [18]", "x [15]", "x [1]"... 

Когда я пытаюсь разобраться в этом результат заканчивается в

"x [0]", "x [15]", "x [18]", "x [1]" 

вместо:

"x [0]", "x [1]", "x [15]", "x [18]" 

Это мой код:

let sortedKeys = sorted(vcd.signals.keys) { 
    var val1 = $0 as! String 
    var val2 = $1 as! String 

    return val1 < val2 
} 

Любая идея, как я могу исправить эту проблему?

+0

Ваши 'x [0], x [18], x [15], ...' есть 'String' каждый? –

+0

да каждая из них строка – JPM

+0

Где строки? Можете ли вы поставить кавычки вокруг фактических строк, пожалуйста. – Fogmeister

ответ

3

Ваша задача прийти связана с сравнения, например, увидеть, что происходит, когда вы сравниваете две следующие строки:

println("x [15]" < "x [1]") // true 

Это потому, что лексикография по умолчанию компаратор идет посимвольно, позиция по позиции сравнения и конечно 5 в положении 3 меньше ] в положении 3:

println("5" < "]") // true 

для пояснялось выше вам необходимо создать собственный компаратор, но только для сравнения количес rs внутри [$0]. Для достижения этой цели я использую регулярные выражения, чтобы соответствовать любым цифрам в скобках, как следующий образом:

func matchesForRegexInText(regex: String!, text: String!) -> [String] { 

    let regex = NSRegularExpression(pattern: regex, 
     options: nil, error: nil)! 
    let nsString = text as NSString 
    let results = regex.matchesInString(text, 
     options: nil, range: NSMakeRange(0, nsString.length)) 
     as! [NSTextCheckingResult] 
    return map(results) { nsString.substringWithRange($0.range)} 
} 

var keysSorted = keys.sorted() { 

     var key1 = $0 
     var key2 = $1 

     var pattern = "([0-9]+)" 
     var m1 = self.matchesForRegexInText(pattern, text: key1) 
     var m2 = self.matchesForRegexInText(pattern, text: key2) 

     return m1[0] < m2[0] 
} 

В приведенном выше регулярном выражении Я предполагаю, что число появляется только в скобках и соответствую любому числу внутри String, но не стесняйтесь изменять регулярное выражение, если хотите достичь чего-то большего. Затем вы достигаете следующего:

println(keysSorted) // [x [0], x [1], x [15], x [18]] 

Я надеюсь, что это поможет вам.

1

Проблема, с которой вы сталкиваетесь, является замыкающим символом скобки ']', поступающим после цифр. Это означает, что «18» меньше «1» ». Пока все ваши строки разделяют форму «[цифры]», вы можете удалить закрывающую фигурную скобку, отсортировать строки, добавить заключительную фигуру обратно в свой последний массив. Ниже приведенный ниже код работает для Swift 2:

let arr = ["x [0]", "x [18]", "x [15]", "x [1]"] 
let sorted = arr.map { $0.substringToIndex($0.endIndex.predecessor()) }.sort().map { $0 + "]" } 

print(sorted)