简体   繁体   English

迅速排序NSArray

[英]Swift sort NSArray

I have a problem with my sorting algorithm. 我的排序算法有问题。

My NSArray (here vcd.signals.key ) contains values of Strings for example: 我的NSArray (在这里vcd.signals.key )包含Strings的值,例如:

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

When I try to sort this the result ends up in 当我尝试对结果进行排序时

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

instead of: 代替:

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

This is my code: 这是我的代码:

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

    return val1 < val2
 }

Any idea how I can fix this issue? 您知道如何解决此问题吗?

Your problem come associated with your comparison , for example see what happen when you compare the two following strings: 您的问题与您的比较有关,例如,比较以下两个字符串时会发生什么:

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

This is because the default lexicography comparer goes character for character, position by position comparing ,and of course 5 in position 3 is less than ] in position 3: 这是因为默认词典编辑比较器逐个字符地逐个字符地进行比较,当然位置3中的5小于位置3中的]

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

For the explained above you need to create you own comparer but , only compare for the numbers inside the [$0] . 对于上面解释的内容,您需要创建自己的比较器,但是,只需要比较[$0]的数字即可。 For achieve this I use regular expressions to match any numbers inside the brackets like in the following way: 为此,我使用正则表达式匹配方括号内的任何数字,如下所示:

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

In the above regular expression I assume that the numbers only appears inside the brackets and match any number inside the String , but feel free to change the regular expression if you want to achieve anything more. 在上面的正则表达式中,我假设数字仅出现在方括号内,并且与String内的任何数字匹配,但是如果您想实现更多功能,可以随时更改正则表达式。 Then you achieve the following: 然后,您将达到以下目的:

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

I hope this help you. 希望对您有所帮助。

The issue you are running into is the closing brace character ']' comes after digits. 您遇到的问题是大括号字符']'出现在数字后面。 This means that "18" is less than "1]". 这意味着“ 18”小于“ 1]”。 As long as all your strings share the form of "[digits]" then you can remove the closing brace, sort the strings, add the closing brace back to your final array. 只要您所有的字符串都共享“ [digits]”的形式,就可以删除右括号,对字符串进行排序,然后将右括号重新添加到最终数组中。 The code below works for Swift 2: 以下代码适用于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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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