说我有一系列这样的词典:
[
["name": "Jack", "age": 20],
["name": "Molly", "age": 21],
["name": "Kyle", "age": 34],
["name": "Jenny", "age": 18],
]
还有像这样的字符串数组:
["Kyle, Jack"]
我希望使用字符串数组对字典数组进行过滤,使其最终像:
[
["name": "Kyle", "age": 34],
["name": "Jack", "age": 20],
]
这是因为我希望在集合视图中仅显示第一个数组中的项(如果它们的名称在第二个数组中(即只有字符串的项))。还有其他集合视图,每个视图将使用不同的字符串数组进行过滤。
我该怎么做?
我尝试做类似的事情:
if nameArray[indexPath.item] == dictionaryArray[indexPath.item]["name"] {
//code for cell here
}
但是它不会按字符串顺序显示单元格。它将执行以下操作:
[empty cell] [Jack's cell]
谢谢!
答案 0 :(得分:2)
您可以使用map
:
arrStrings.map { str in
return arrDicts[arrDicts.index(where: { dict in
if let name = dict["name"] as? String {
return name == str
}
return false
})!]
}
这不是很有效,但是由于您要保持顺序,我认为有必要搜索整个词典数组。
这假定存在具有由字符串数组指定的名称的字典。如果它们可能存在或不存在,您可以尝试:
arrStrings.compactMap { str -> [String: Any]? in
guard let index = arrDicts.index(where: { dict in
if let name = dict["name"] as? String {
return name == str
}
return false
}) else { return nil }
return arrDicts[index]
}
答案 1 :(得分:0)
作为替代方案,我们可以使用@Sweeper's answer中类似的compactMap(_:)
方法,但是:
Array
的{{3}}方法而不是first(where:)
(以前称为index(where:)
)Optional
的{{3}}方法有条件地执行name
(String
)谓词使用上述方法,我们可以将过滤后的字典数组(根据String
名称的数组的顺序进行计算)计算为:
let filteredAndOrderedDicts = arrStrings.compactMap { name in
arrDicts.first { dict in
(dict["name"] as? String).map { $0 == name } ?? false
}}
print(filteredAndOrderedDicts) // [["name": "Kyle", "age": 34],
// ["name": "Jack", "age": 20]]
对于这个给定的问题,我相信first(where:)
的语义比index(where:)
/ firstIndex(where:)
更好,而使用可选绑定(guard let
/ if let
)与Optional
的{{1}}是偏好问题(也许是简洁还是简洁)。
在上面的示例中,使用的输入依据:
map(_:)