如何在Swift中获取多层嵌套字典内的指定数据
报错原因说明
MV["Nobody"]报错:MV的类型是[[String: [[String: Any]]]],最外层是数组,仅支持整数下标访问,无法直接用字符串作为下标取值- 遍历代码报错:
MV的每一个元素是仅包含单个键值对的字典,不是元组,需要先取出每个字典的key和value再处理,正确遍历写法如下:
for movieItem in MV { guard let movieName = movieItem.keys.first, let movieData = movieItem[movieName] else { continue } print("电影名:\(movieName)") print("电影数据:\(movieData)") }
需求实现代码
1. 获取电影"Nobody"对应的"IMAGE"值
// 首先从外层数组筛选出Nobody对应的所有属性 guard let nobodyAttrs = MV.first(where: { $0.keys.contains("Nobody") })?["Nobody"] else { print("未找到电影Nobody的相关数据") exit(0) } // 从属性数组中筛选IMAGE对应的键值对 if let imageAttr = nobodyAttrs.first(where: { $0.keys.contains("IMAGE") }), let imageName = imageAttr["IMAGE"] as? String { print(imageName) // 输出:Nobody.png }
2. 获取BestMoments的成员数量
// 获取Nobody的BestMoments数量 if let momentsAttr = nobodyAttrs.first(where: { $0.keys.contains("BestMoments") }), let momentsList = momentsAttr["BestMoments"] as? [Any] { print(momentsList.count) // 输出:3 } // 获取Godzilla vs. Kong的BestMoments数量 guard let kongAttrs = MV.first(where: { $0.keys.contains("Godzilla vs. Kong") })?["Godzilla vs. Kong"], let kongMomentsAttr = kongAttrs.first(where: { $0.keys.contains("BestMoments") }), let kongMomentsList = kongMomentsAttr["BestMoments"] as? [Any] else { print("未找到对应电影数据") exit(0) } print(kongMomentsList.count) // 输出:4
3. 获取"Nobody"对应BestMoments内的"Survive"组数据
if let momentsAttr = nobodyAttrs.first(where: { $0.keys.contains("BestMoments") }), let momentsList = momentsAttr["BestMoments"] as? [[Any]] { // 筛选首个元素为Survive的数组 guard let surviveItem = momentsList.first(where: { $0.first as? String == "Survive" }) else { print("未找到对应数据") exit(0) } print(surviveItem) // 输出:["Survive", 120, 8] // 可通过下标单独取值:surviveItem[0]为"Survive",surviveItem[1]为120,surviveItem[2]为8 }
结构优化建议
你当前的数组套单键字典的结构访问效率很低,建议调整为外层是字典,key为电影名,value为该电影的属性字典,优化后结构及访问方式如下:
var optimizedMV: [String: [String: Any]] = [ "Nobody": [ "YEAR" : "2021", "IMAGE" : "Nobody.png", "GENRE" : "Action/Thriller", "DURATIONhours" : 1, "DURATIONmintues" : 36, "DURATIONseconds" : 17, "BestMoments" : [["Win", 25, 5], ["Survive", 120, 8], ["Lose", 240, 15]] ], "Godzilla vs. Kong": [ "YEAR" : "2021", "IMAGE" : "GodzillaVsKong.png", "GENRE" : "Action/Sci-fi", "DURATIONhours" : 1, "DURATIONmintues" : 22, "DURATIONseconds" : 45, "BestMoments" : [["Win", 34, 6], ["Survive", 120, 8], ["Twist", 233, 3], ["Lose", 340, 12]] ] ] // 优化后直接通过key取值即可 // 取IMAGE值 print(optimizedMV["Nobody"]?["IMAGE"] as? String ?? "") // 取BestMoments数量 print((optimizedMV["Nobody"]?["BestMoments"] as? [Any])?.count ?? 0) // 取Survive组数据 let moments = optimizedMV["Nobody"]?["BestMoments"] as? [[Any]] ?? [] let surviveItem = moments.first { $0.first as? String == "Survive" }
内容的提问来源于stack exchange,提问作者ooenomel2003
相关产品推荐
相关产品推荐

