Swift 在结构中制作 init 字典

Posted

技术标签:

【中文标题】Swift 在结构中制作 init 字典【英文标题】:Swift make init Dictionary in struct 【发布时间】:2021-12-15 11:16:30 【问题描述】:

我有一个 [[String:Any]] 我想把它放在我的结构数据模型中,因为我想编辑数据,谁能告诉我应该如何制作可以包含这种类型的字典字典?

这是 var 字典:

let toolListDict : [[String:Any]] = [
    [
        "Name": "Wrench",
        "qty": 6
    ],
    [
        "Name": "Cutter",
        "qty": 15
    ],
    [
        "Name": "Pliers",
        "qty": 12
    ],
    [
        "Name": "ScrewDriver",
        "qty": 13
    ],
    [
        "Name": "Welding Machine",
        "qty": 3
    ],
    [
        "Name": "Welding Glasses",
        "qty": 7
    ],
    [
        "Name": "Hammer",
        "qty": 4
    ],
    [
        "Name": "Measuring Tape",
        "qty": 9
    ],
    [
        "Name": "Alan Keyset",
        "qty": 4
    ],
    [
        "Name": "Air Compressor",
        "qty": 2
    ]
]

到目前为止,这是我创建的模型数据:

struct Tools: Codable
var name: String
var qty : Int

init(name: String, qty: Int)
    self.name = name
    self.qty = qty

如何在我的结构中创建一个 init 字典,以便我可以将它放入我的结构中?

我只想像这样将该字典添加到我的数据模型中:

let tool = try Tools(dict: toolListDict)

如果我的英语有点混乱,我希望我解释得足够清楚,谢谢。

【问题讨论】:

你可以使用类似DictionaryDecoder from this的东西 @Sweeper 啊谢谢我看看这个 【参考方案1】:

这里有两种可能的解决方案。第一个是将字典元素映射到结构中。为此,我们需要一个可失败的初始化程序,因为我们使用的是compactMap

请注意,我冒昧地更改了一些自定义类型的命名

struct Tool: Codable 
    var name: String
    var quantity : Int

    init?(name: String?, quantity: Int?) 
        guard let name = name, let quantity = quantity else 
            return nil
        
        self.name = name
        self.quantity = quantity
    

    //...

那么转换toolListDict就变得简单了

let tools = toolListDict.compactMap  
    Tool(name: $0["Name"] as? String, quantity: $0["qty"] as? Int) 


另一种选择是首先使用JSONSerialization 对字典进行编码,然后使用JSONDecoder 解码结果,为此我们需要将CodingKey 枚举添加到自定义类型

enum CodingKeys: String, CodingKey 
    case name = "Name"
    case quantity = "qty"

编码/解码是这样完成的

do 
    let data = try JSONSerialization.data(withJSONObject: toolListDict)
    let tools = try JSONDecoder().decode([Tool].self, from: data)
    //...
 catch 
    print(error)

【讨论】:

以上是关于Swift 在结构中制作 init 字典的主要内容,如果未能解决你的问题,请参考以下文章

从嵌套结构(带有其他结构的数组)创建字典 Swift

将字典映射到 Swift 中的结构数组

在 Swift 中解码 JSON API - 重复的结构名称

在 Metal File 中访问 swift 结构或类

使用 PropertyListSerialization 在 swift 2 中制作字典

为啥 Swift 类需要 init 而不是 Swift struct