如何通过键过滤 NSArray:值,即在 NSDictionary
Posted
技术标签:
【中文标题】如何通过键过滤 NSArray:值,即在 NSDictionary【英文标题】:How to filter a NSArray by Key:value, that is in a NSDictionary 【发布时间】:2018-02-14 08:33:18 【问题描述】:我试图弄清楚如何通过值“名称”过滤掉 NSArrays 的字典
// Is an Array of a dictionary, by key : values
var teamFilteredList = [[String:Any]]()
var teamList = [[String:Any]]()
获取:
let string = "https://api/connect/"
let url = NSURL(string: string)
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "GET"
let session = URLSession.shared
let tache = session.dataTask(with: request as URLRequest) (data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSArray
print(jsonObj)
teamList = jsonObj as! [[String : Any]]
DispatchQueue.main.async
self.teamCollectionView.reloadData()
tache.resume()
此代码是结果并被放入 teamList
JSON:
(
id = 1;
logo = "testLogo";
name = "testTeam1";
"url" = "https://example.com";
,
id = 2;
logo = "testLogo";
name = "testTeam2";
"url" = "https://example.com";
,
id = 3;
logo = "testLogo";
name = "testTeam3";
"url" = "https://example.com";
)
放入 teamList 后的外观示例:
let example = [[id: "1", logo: "image", name: "testTeam1", url: "https"], [id: "2", logo: "image", name: "testTeam2", url: "https"]]
试图过滤的代码:
let array2Name = teamFilteredList.flatMap $0["name"]
teamFilteredList = teamList.reduce(teamFilteredList, result, value in
!array2Name.contains(where: $0 as! _OptionalNilComparisonType == value["testTeam3"] ) ? result + [value]: result
)
到目前为止,这段代码很糟糕。但是网上没有其他东西可以告诉我如何做到这一点。所以我被卡住了。
导致崩溃:
无法转换“__NSCFString”类型的值
更新:
我有一个集合视图,它是由 NSURL 从获取中填充的,它给了我一个充满 NSArrays 的字典,我想通过一个已经在 NSArray 索引中的值过滤掉该字典中的所有 NSArray 索引键:“名称”
此链接最终答案中已回答的问题,但它不是最新的并且会产生错误。 here
【问题讨论】:
无法转换类型为 '__NSCFString 的值。您正在尝试将 String 存储到另一种数据类型。所以它越来越崩溃 好的,谢谢,必须有一个更简单的方法来做到这一点。 @McDonal_11 你想做什么? 我把它放在更新中@McDonal_11 鼓励您使用自定义类或结构而不是字典。它让事情变得简单。 【参考方案1】:使用自定义结构和JSONDecoder
会容易得多
创建一个结构
struct Team : Decodable
let id : Int
let logo : String
let name : String
let url : URL
创建数组
var teamList = [Team]()
var teamFilteredList = [Team]()
解码 JSON
let string = "https://api/connect/"
let url = URL(string: string)!
let task = URLSession.shared.dataTask(with: url) (data, response, error) in
if let error = error print(error); return
do
self.teamList = try JSONDecoder().decode([Team].self, from: data!)
DispatchQueue.main.async
self.teamCollectionView.reloadData()
catch
print(error)
task.resume()
并过滤数组
teamFilteredList = teamList.filter $0.name == "testTeam3"
【讨论】:
【参考方案2】:尝试使用这个谓词
teamFilteredList.filter( fromDict in return !array2Name.contains(where: $0 == fromDict["name"] as? String ?? ""))
诀窍在于 Swift 的错误没有表现力。它说don't use where
,为什么?因为编译器真的需要一个字符串,因为你的闭包不正确。
如果array2Name
也是字典。尝试将where
子句更改为:
where: ($0["name"] as? String ?? "<<Empty1>>") == (fromDict["name"] as? String ?? "<<Empty2>>")
所以整个函数是:
teamFilteredList.filter( fromDict in return !array2Name.contains(where: ($0["name"] as? String ?? "<<Empty1>>") == (fromDict["name"] as? String ?? "<<Empty2>>") ))
如果你想学习更有效的函数式编程并且不介意一些 javascript,试试这个
Learn Effective Functional Programming in JavaScript)
【讨论】:
比以往任何时候都更接近,大声笑虽然我收到错误'二进制运算符'=='不能应用于'[String:Any]'和'String'类型的操作数 array2Name 我用已经填充的变量 teamList 替换。我得到了错误 看来array2Name
不是字符串数组。这段代码是关于 array2Name 是一个字符串数组。所以试试这个where: ($0["name"] as? String ?? "<<Empty1>>" == fromDict["name" as? String ?? "<<Empty2>>"])
这样做是为了使 > 和 > 都不是字符串时条件失败以上是关于如何通过键过滤 NSArray:值,即在 NSDictionary的主要内容,如果未能解决你的问题,请参考以下文章