You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 5中如何过滤包含嵌套字典的字典?

如何过滤嵌套字典并将匹配值存入filteredData?

首先,咱们先看看你代码里的问题:你把字典Data转成NSArray然后过滤,最后还试图转成[String],这肯定不对——因为你的原数据是[Int : [String : String]]类型,转成数组会丢失原字典的key信息,而且类型转换完全不匹配,运行时肯定会崩溃。

针对嵌套字典的过滤,咱们用Swift原生的API就能轻松搞定,不用绕到NSPredicate(当然也能用,但原生方法更直观)。下面分两种场景给你方案:

场景1:搜索嵌套字典中任意值是否包含关键词

如果只要嵌套字典里的任意一个值包含搜索文本(忽略大小写),就保留这个条目,可以这么写:

// 先安全获取搜索文本,避免强制解包崩溃
guard let searchText = searchController.searchBar.text?.lowercased(), !searchText.isEmpty else {
    filteredData = Data // 搜索文本为空时返回全部数据
    return
}

// 过滤字典:保留那些嵌套字典中至少有一个值包含搜索文本的条目
filteredData = Data.filter { _, valueDict in
    valueDict.values.contains { $0.lowercased().contains(searchText) }
}

代码解释:

  • Data.filter会遍历字典的每一组键值对(key和对应的嵌套字典valueDict)
  • valueDict.values.contains检查嵌套字典的所有值中,是否存在任意一个字符串转小写后包含搜索文本(转小写是为了实现忽略大小写的匹配,对应你原来的[c]选项)

场景2:只搜索嵌套字典中特定key对应的值

如果你只想匹配嵌套字典里某个特定key(比如只搜"username"对应的值),可以修改过滤条件:

guard let searchText = searchController.searchBar.text?.lowercased(), !searchText.isEmpty else {
    filteredData = Data
    return
}

filteredData = Data.filter { _, valueDict in
    // 只检查嵌套字典中"username"这个key对应的值
    if let targetValue = valueDict["username"]?.lowercased() {
        return targetValue.contains(searchText)
    }
    return false
}

如果你一定要用NSPredicate

如果习惯用NSPredicate,也可以这么实现(同样以搜索任意值为例):

guard let searchText = searchController.searchBar.text else {
    filteredData = Data
    return
}

let predicate = NSPredicate(format: "ANY values CONTAINS[c] %@", searchText)
filteredData = Data.filter { predicate.evaluate(with: $0.value) }

最后提醒:

尽量避免用!强制解包searchController.searchBar.text,万一文本为空会直接崩溃,用guard let或者if let做安全解包更稳妥。

内容的提问来源于stack exchange,提问作者GoForIt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:05:41