过滤和排序 swift 数组

Posted

技术标签:

【中文标题】过滤和排序 swift 数组【英文标题】:Filter and sort swift array 【发布时间】:2016-08-02 10:31:52 【问题描述】:

我有一个要过滤的 swift 数组,这是数组

let array = [apple,workshops,shopping,sports,parties,pantry,pen] 

我想过滤数组,使以搜索字符串开头的项目出现在仅包含搜索字符串的项目之前

所以当我搜索例如 p 时,结果应该是某种方式

let array = [parties,pantry,pen,apple,workshops,shopping,sports] 

我试过了

tagSearchResults = tagSearchResults.filter( (interestTag:InterestTag) -> Bool in
            let tmp: NSString = interestTag.tag
            let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
            return range.location != NSNotFound
        )

但这给了我所有包含搜索字符串的字符串。

各位,我该怎么做呢

【问题讨论】:

您要查找的内容可以分两步完成:首先过滤(正如您已经在做的那样),然后进行(自定义)排序。 【参考方案1】:

你可以写

 let result = words
    .filter  $0.contains(keyword) 
    .sorted  ($0.hasPrefix(keyword) ? 0 : 1) < ($1.hasPrefix(keyword) ? 0 : 1) 

示例

let words = ["apple", "workshops", "shopping", "sports", "parties", "pantry", "pen", "cat", "house"]
let keyword = "p"
let result = words
    .filter  $0.contains(keyword) 
    .sorted  ($0.hasPrefix(keyword) ? 0 : 1) < ($1.hasPrefix(keyword) ? 0 : 1) 

// ["pen", "pantry", "parties", "apple", "workshops", "shopping", "sports"]

【讨论】:

这个可能可以工作,但是严格来说sort()方法要求比较方法是"strict weak ordering",而这里不是这样:不是不自反(除非我弄错了)。 @MartinR:你是对的MartinR,感谢你的指出。我刚刚更新了我的代码。 现在应该可以了。不过要注意一点:Int(someBool) 进行了 Bool -&gt; NSNumber -&gt; Int 转换,这并不明显,可能出乎意料。 @MartinR:好的,我将Int(someBool) 替换为三元条件运算符。感谢您分享您的观察!我真的很感激。 现在您应该再次测试您的代码。它不会打印您声称的内容:)【参考方案2】:

试试这个。首先,它过滤数组以删除那些不包含搜索字符串的元素,然后使用自定义排序来选择以搜索字符串开头的项目。一般来说,使用笛卡尔方法将问题分解为更小的子问题,而不是尝试一步解决所有问题。

let searchString = "p"
let array = ["apple", "workshops", "shopping", "sports", "parties", "pantry", "pen", "xyzzy"]

let filteredArray = array.filter( $0.contains(searchString) )
filteredArray // drops xyzzy

let sortedArray = filteredArray.sorted(isOrderedBefore:  
    switch ($0.hasPrefix(searchString), $1.hasPrefix(searchString)) 
    case (true, true):
        return $0 < $1
    case (true, false):
        return true
    case (false, true):
        return false
    case (false, false):
        return $0 < $1
    

)
sortedArray // "pantry", "parties", "pen", "apple", "shopping", "sports", "workshops"] as required

【讨论】:

我误解了这个问题,这是正确的答案。 这是一个比接受的答案更好的答案,因为它对子组中匹配和不匹配的项目进行排序。做得好。 (已投票) 让 sortedArray = filtersArray.sorted(isOrderedBefore: let a = $0.hasPrefix(searchString); return (a == $1.hasPrefix(searchString)) ? $0 【参考方案3】:

另一种方式:

let searchString = "p"
let array = ["apple", "workshops", "shopping", "sports", "parties", "pantry", "pen", "xyzzy"]
let result = array.filter$0.containsString(searchString)
    .map($0.hasPrefix(searchString) ? 0 : 1, $0)
    .sort$0 < $1
    .map$1
print(result) //->["pantry", "parties", "pen", "apple", "shopping", "sports", "workshops"]

(我不知道为什么,但我的 Xcode 花了很多时间来编译这些行。相信这最终会按预期编译和运行。)

【讨论】:

以上是关于过滤和排序 swift 数组的主要内容,如果未能解决你的问题,请参考以下文章

Swift SearchBar 过滤和更新多个数组

swift 删除排序数组中的重复项

过滤两个数组Swift

Swift 对数组进行排序并返回索引和元素的数组

如何在Vue中对对象数组进行排序和过滤

在 swift 中使用 tableview 和数组过滤器自动完成文本字段