【问题标题】:How to retrieve deeply nested data form SWIFT dictionary?如何从 SWIFT 字典中检索深度嵌套的数据?
【发布时间】:2021-09-14 14:48:19
【问题描述】:

我正在努力实现以下目标,需要您帮助我快速处理字典:

  1. 如何获得“Nobody”“图像”值?它应该是“Nobody.png”
  2. 如何计算 BestMoments 成员的数量? (第一部电影应该是 3,第二部电影应该是 4"
  3. 如何在 Bestmoments 中获取“Nobody”的值(例如:“Survive”、120、8)?
 var MV = [
        ["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" : "Nobody.png"] ,
            ["GENRE" : "Action/Sci-fi"] ,
            ["DURATIONhours" : 1] ,
            ["DURATIONmintues" : 22] ,
            ["DURATIONseconds" : 45] ,
            ["BestMoments" : [["Win", 34, 6], ["Survive", 120, 8], ["Twist", 233, 3], ["Lose", 340, 12]]]
        ]],
    ]

我尝试了以下方法来访问数据(带有结果):

print(MV[0])
// 打印第一部电影的所有数据

print(MV["Nobody"])
// 对下标的调用没有完全匹配

print([MV[0].keys])
// 打印第一部电影的名字,它是键

for (movie, data) in MV2 {
        print(data)
        }

//元组模式不能匹配非元组类型的值 [String : [[String : Any]]]]

【问题讨论】:

  • 你有什么尝试,访问字典到底是什么问题?
  • 再看这个我就明白这并不容易。这个结构的来源是什么,因为它看起来真的很糟糕,也许这里的解决方案是简化数据。
  • @JoakimDanielson 谢谢,我添加了一些尝试(已编辑的问题),之后我无法进一步。你的意思是它不适合这种数据结构吗?
  • 它总是可行的 :) 我的意思是,如果结构更好,它会容易得多。
  • 在使用此数据模型之前,将其转换为可用的东西。首先定义一个好的struct 层次结构,然后考虑如何将数据映射到该层次结构。提示 - 在结果层次结构中应该只有一个(或没有)字典。

标签: swift dictionary


【解决方案1】:

更好地表示数据:

struct BestMoment {
    enum MomentType: String {
        case win = "Win"
        case survive = "Survive"
        case lose = "Lose"
        case twist = "Twist"
    }

    let type: MomentType
    let start: Int
    let duration: Int
}

struct Duration {
    let hours: Int
    let minutes: Int
    let seconds: Int
}

struct Movie {
    let name: String
    let year: Int
    let image: String
    let genre: String
    let duration: Duration
    let bestMoments: [BestMoment]
}

let movies = [
    Movie(
        name: "Nobody",
        year: 2021,
        image: "Nobody.png",
        genre: "Action/Thriller",
        duration: Duration(hours: 1, minutes: 36, seconds: 16),
        bestMoments: [
            BestMoment(type: .win, start: 25, duration: 5),
            BestMoment(type: .survive, start: 120, duration: 8),
            BestMoment(type: .lose, start: 240, duration: 15)
        ]
    ),
    Movie(
        name: "Godzilla vs. Kong",
        year: 2021,
        image: "Nobody.png",
        genre: "Action/Sci-fi",
        duration: Duration(hours: 1, minutes: 22, seconds: 45),
        bestMoments: [
            BestMoment(type: .win, start: 34, duration: 6),
            BestMoment(type: .survive, start: 120, duration: 8),
            BestMoment(type: .twist, start: 233, duration: 3),
            BestMoment(type: .lose, start: 340, duration: 12)
        ]
    )
]

那么你的操作就简单了:

  1. movies.first { $0.name == "Nobody" }?.image
  2. movies.first { $0.name == "Nobody" }?.bestMoments.count
  3. movies.first { $0.name == "Nobody" }?.bestMoments

您甚至可以将您的电影库包装到一个额外的对象中,以简化电影的搜索。

持续时间可能仅以秒表示,并且仅在需要时转换为小时/分钟/秒。 Genre 可能是 enum

【讨论】:

  • 感谢您的努力。测试时出现此错误:'$' 不是标识符;使用反引号将其转义
  • @ooenomel2003 我的错,已修复。
  • @ooenomel2003 那是你的问题。我可以给你代码,但你必须知道如何使用它。
【解决方案2】:

有问题的数据具有非常复杂的数据结构,难以管理。我认为有一个更简单的结构会更好。

但是,您可以通过以下方式访问所需的数据。 尝试打印结果。

/// 1. How to get "Nobody" "Image" value? it should be "Nobody.png"
let imageOfNobady = MV[0]["Nobody"]![1]["IMAGE"]

/// 2. How to the count of BestMoments members? (it should be 3 for first movie and 4 for second movie"
let bestmomentsForNobady = MV[0]["Nobody"]![6]["BestMoments"] as! [Any]
let countOfBestmomentsForNobady = bestmomentsForNobady.count

/// 3. how to get values inside Bestmoments for "Nobody" (like :"Survive", 120, 8)?
let survieInfo = bestmomentsForNobady[1]

【讨论】:

  • 很好的答案,谢谢。对于第三个问题,我实际上想确定一个元素,如“生存”,而不是所有“生存”,120、8 一起
  • @ooenomel2003 “很好的答案”,我不同意这一点,因为这个答案适用于许多硬编码索引。对顶部或子数组进行一点小改动,它就不再起作用了。实际上,既然这么多是硬编码的,那么第一个也可以缩短为let imageOfNobady = "Nobody.png"for instance
  • @JoakimDanielson 是的,我同意你的看法。这不是一个“很好的答案”。但这无济于事,因为原始数据结构不好。所以,我认为有一个更简单的数据结构会更好。
猜你喜欢
  • 2021-12-29
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 2018-09-03
  • 2021-01-03
  • 2018-03-19
  • 2015-11-17
  • 2016-12-18
相关资源
最近更新 更多