I have a problem with my sorting algorithm.
My NSArray
(here vcd.signals.key
) contains values of Strings for example:
"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:
println("5" < "]") // true
For the explained above you need to create you own comparer but , only compare for the numbers inside the [$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. 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]". 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. The code below works for 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)
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.