有人可以告诉我一种以正确的方式过滤/排序我的阵列的方法吗?
我目前拥有的Playground如下:
//: Playground - noun: a place where people can play
import UIKit
var candidates: NSArray = ["Berlin-Lichtenberg", "Berlin-Lichterfelde Ost", "Berlin-Lichterfelde West", "Braunsdorf-Lichtenwalde", "Darmstadt-Lichtwiese", "Lichtenberg (Erzgeb)", "Lichtenfels", "Lichtenrade", "Lichtenstein (Sachs)", "Lichtentanne (Sachs)", "Lichtentanne (Thür)", "Lichtenthal", "Lichterfelde Süd", "Rostock Lichtenhagen", "Hamburg", "München", "Köln", "Bonn"]
var root = "Licht"
var predicate = NSPredicate(format: "(SELF BEGINSWITH[c] %@) OR (SELF MATCHES[c] %@)", root, NSString(format: ".*[^\\w]%@.*", root))
var filteredArray = NSMutableArray(array: candidates.filteredArrayUsingPredicate(predicate))
println(filteredArray)
这将打印出以下内容:
(
"Berlin-Lichtenberg",
"Berlin-Lichterfelde Ost",
"Berlin-Lichterfelde West",
"Braunsdorf-Lichtenwalde",
"Darmstadt-Lichtwiese",
"Lichtenberg (Erzgeb)",
Lichtenfels,
Lichtenrade,
"Lichtenstein (Sachs)",
"Lichtentanne (Sachs)",
"Lichtentanne (Thu\U0308r)",
Lichtenthal,
"Lichterfelde Su\U0308d",
"Rostock Lichtenhagen"
}
这一切都运行正常,但我需要的数组的排序是另一个,我不能正确:(
这是它的样子:
(
"Lichtenberg (Erzgeb)",
Lichtenfels,
Lichtenrade,
"Lichtenstein (Sachs)",
"Lichtentanne (Sachs)",
"Lichtentanne (Thu\U0308r)",
Lichtenthal,
"Lichterfelde Su\U0308d",
"Berlin-Lichtenberg",
"Berlin-Lichterfelde Ost",
"Berlin-Lichterfelde West",
"Braunsdorf-Lichtenwalde",
"Darmstadt-Lichtwiese",
"Rostock Lichtenhagen"
)
所以我需要的结果以我的搜索字符串(root)开头,这是“Licht”开头的,然后它应该显示其中只包含它的其他字符。
我怎么能够实现这个目标?
答案 0 :(得分:4)
我建议使用Swift数组类型而不是NSArray
,并使用filter
结合sort
方法,该方法采用闭包来确定2个元素的排序顺序。
在您的情况下,它将实现为:
var candidates = ["Berlin-Lichtenberg", "Berlin-Lichterfelde Ost", "Berlin-Lichterfelde West", "Braunsdorf-Lichtenwalde", "Darmstadt-Lichtwiese", "Lichtenberg (Erzgeb)", "Lichtenfels", "Lichtenrade", "Lichtenstein (Sachs)", "Lichtentanne (Sachs)", "Lichtentanne (Thür)", "Lichtenthal", "Lichterfelde Süd", "Rostock Lichtenhagen", "Hamburg", "München", "Köln", "Bonn"]
let root = "Licht"
var results = candidates.filter {
$0.rangeOfString(root) != nil
}.sorted { (lhs: String, rhs: String) -> Bool in
if startsWith(lhs, root) {
if (startsWith(rhs, root)) {
// Both start with root, so return the string comparison
return lhs < rhs
}
// lhs starts with root, rhs doesn't, so lhs comes first
return true
}
// rhs starts with root, lhs doesn't, so rhs comes first
if (startsWith(rhs, root)) {
return false
}
// return the normal string comparison
return lhs < rhs
}
答案 1 :(得分:2)
let candidates: [String] = ["Berlin-Lichtenberg", "Berlin-Lichterfelde Ost", "Berlin-Lichterfelde West", "Braunsdorf-Lichtenwalde", "Darmstadt-Lichtwiese", "Lichtenberg (Erzgeb)", "Lichtenfels", "Lichtenrade", "Lichtenstein (Sachs)", "Lichtentanne (Sachs)", "Lichtentanne (Thür)", "Lichtenthal", "Lichterfelde Süd", "Rostock Lichtenhagen", "Hamburg", "München", "Köln", "Bonn"].sorted{$0 < $1}
let root = "Licht"
var filtered: [String] = []
filtered += candidates.filter{$0.hasPrefix(root)}
filtered += candidates.filter{$0.hasPrefix(root) == false && $0.rangeOfString(root, options: nil) != nil}
println(filtered) // "[Lichtenberg (Erzgeb), Lichtenfels, Lichtenrade, Lichtenstein (Sachs), Lichtentanne (Sachs), Lichtentanne (Thür), Lichtenthal, Lichterfelde Süd, Berlin-Lichtenberg, Berlin-Lichterfelde Ost, Berlin-Lichterfelde West, Braunsdorf-Lichtenwalde, Darmstadt-Lichtwiese, Rostock Lichtenhagen]"