ios - 在 Swift 中使用关键字过滤数组数组

标签 ios arrays swift filter

let searchResultItem1 = SearchResult()
searchResultItem1.type = "contact"
searchResultItem1.typeTitle = "CONTACTS"
searchResultItem1.results = ["Joe" , "Smith" , "Alan" , "Nick" , "Jason"]

let searchResultItem2 = SearchResult()
searchResultItem2.type = "address"
searchResultItem2.typeTitle = "ADDRESS"
searchResultItem2.results = ["829 6th Street North Fullerton" , "669   Windsor Drive Randallstown" , "423 Front Street Lacey"]
searchResults.append(searchResultItem1)
searchResults.append(searchResultItem2)

当我搜索“al”时,我希望返回一个结果为“[Alan]”的 SearchResult 和一个结果为“["669 Windsor Drive Randallstown"]”的 SearchResult

我试过下面的过滤器,但返回空数组。

let results = searchResults.filter({$0.results.contains("al")})

最佳答案

正如其他两个答案所指出的,您正在结果数组中搜索值为“al”的项目。您想要的实际上是返回一组结果,缩小到仅匹配的结果:

struct SearchResult {
    let type:String
    let typeTitle:String
    let results:[String]
}

let searchResultItem1 = SearchResult(
    type: "contact",
    typeTitle: "CONTACTS",
    results: ["Joe" , "Smith" , "Alan" , "Nick" , "Jason"]
)

let searchResultItem2 = SearchResult(
    type:"address",
    typeTitle: "ADDRESS",
    results:["829 6th Street North Fullerton" , "669   Windsor Drive Randallstown" , "423 Front Street Lacey"]
)

var searchResults = [ searchResultItem1, searchResultItem2 ]

现在,再次为了方便起见,为 String 定义一个不区分大小写的 contains 函数:

extension String {
    func containsIgnoreCase(substring:String) -> Bool {
        return rangeOfString(
            substring,
            options: .CaseInsensitiveSearch,
            range: startIndex..<endIndex,
            locale: nil)?.startIndex != nil
    }
}

注意 String 已经有一个 contains 函数,它只是区分大小写,但如果这就足够了,你甚至不需要定义自己的。

现在,您可以使用 map 删除不包含您的搜索字符串的结果:

searchResults = searchResults.map({
    return SearchResult(
        type: $0.type,
        typeTitle: $0.typeTitle,
        results: $0.results.filter({
            $0.containsIgnoreCase("al")
        })
    )
})

而且,据推测,您还想消除任何没有实际结果的 SearchResult,因此请使用过滤器:

searchResults = searchResults.filter { $0.results.count > 0 }

当然,整个事情可以串成一个表达式:

searchResults = searchResults.map({
    return SearchResult(
        type: $0.type,
        typeTitle: $0.typeTitle,
        results: $0.results.filter({
            $0.contains("al")
        })
    )
}).filter { $0.results.count > 0 }

并且,您可以使用 flatMap 进一步减少一些迭代,它类似于 map,但消除了任何 nil 值:

searchResults = searchResults.flatMap {
    let results = $0.results.filter { $0.containsIgnoreCase("al") }
    if results.count > 0 {
        return SearchResult(type: $0.type, typeTitle: $0.typeTitle, results: results)
    } else {
        return nil
    }
}

关于ios - 在 Swift 中使用关键字过滤数组数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36002066/

相关文章:

ios - 适用于 iOS 的 OpenGL 对象加载器

javascript - 复制对象数组

c - 如何在C中对数字数组进行排序

ios - 仅为目标 V​​iewController 设置导航栏

ios - 代码 : missing required module error

ios - UITabBarButton 无需切换到另一个 View

ios - 从 Storyboard 中实例化 View Controller 时应用程序崩溃

python - numpy ndarray 索引 - 从元组中检索索引

ios - Firebase 屏幕跟踪两次调用 "screen_view"事件

swift - arc4random() 和 arc4random_uniform() 不是真正随机的?