【问题标题】:Swift 3 - Compare key values from two different dictionaries and update one of them if key value matchesSwift 3 - 比较两个不同字典中的键值并在键值匹配时更新其中一个
【发布时间】:2018-02-04 04:17:25
【问题描述】:

我有两个字典数组:

Dict 1 = 
[{"id":"100", "name":"Matt", "phone":"0404040404", "address":"TBC"}
,{"id":"110", "name":"Sean", "phone":"0404040404", "address":"TBC"}
, {"id":"120", "name":"Luke", "phone":"0404040404", "address":"TBC"}]

Dict 2 = 
[{"id":"100", "address":"1 Main Street"}
,{"id":"110", "address":"2 Main Road"}
, {"id":"120", "address":"3 Main Street"}]

我想比较 Dict 2 中每个字典的 key:value 对 id 和 Dict 1,如果 id 匹配,则更新对应的地址Dict2中的值的Dict 1。

所以期望的输出应该是:

Dict 1 = 
[{"id":"100", "name":"Matt", "phone":"0404040404", "address":"1 Main Street"}
,{"id":"110", "name":"Sean", "phone":"0404040404", "address":"2 Main Road"}
, {"id":"120", "name":"Luke", "phone":"0404040404", "address":"3 Main Street"}]

编辑

根据要求,这里提供了有关我如何解析数据的更多信息。我得到 Dict1 和 Dict2 作为对 HTTP URL 调用 btw 的响应。而且,我在解析时使用 [Dictionary] 类型的字典。

        let Task1 = URLSession.shared.dataTask(with: URL!) { (Data, response, error) in
            if error != nil {
                print(error)
            } else {
                if let DataContent = Data {
                    do {
                        let JSONresponse1 = try JSONSerialization.jsonObject(with: DataContent, options: JSONSerialization.ReadingOptions.mutableContainers)
                        print(JSONresponse1)

                        for item in JSONresponse1 as! [Dictionary<String, Any>] {
                            //Parse here    
                        }
                    }
                    catch { }
                    DispatchQueue.main.async(execute: {
                        self.getAddressTask()
                    })
                }
            }
        }
        Task1.resume()
    }

JSONResponse1 是字典 1

然后在上面调用的 getAddressTask() 函数中,我执行 HTTP URL 调用以获取 Dict 2

    let AddressTask = URLSession.shared.dataTask(with: URL2!) { (Data, response, error) in
        if error != nil {
            print(error)
        } else {
            if let DataContent = Data {
                do {
                    let JSONresponse2 = try JSONSerialization.jsonObject(with: timeRestrictionsDataContent, options: JSONSerialization.ReadingOptions.mutableContainers)
                    print(JSONresponse2)
                        for item in JSONresponse2 as! [Dictionary<String, Any>] {
                            //Parse here    
                        }
                catch { }
                self.compileDictionaries()
            }
        }
    }
    AddressTask.resume()

JSONResponse2 是 Dict2

在 compileDictionaries() 中,我想得到 所需的输出,如上所示。

【问题讨论】:

  • 您没有两本词典。你有两个字典数组
  • Leo 这就是我在第一行中提到的。但这将是这些数组中每个字典的比较。
  • 我建议你使用 Codable 协议而不是使用字典来构造你的数据
  • 你拥有的是两个 json 字符串。顺便说一句,您应该展示您的尝试以及您面临的问题

标签: swift dictionary compare key-value


【解决方案1】:

您应该使用 Codable 协议来构建您的数据,并创建一个变异方法来更新您的联系人。如果您在更新联系人后需要一组联系人,您只需使用 JSONEncoder 对联系人进行编码:

struct Contact: Codable, CustomStringConvertible {
    let id: String
    var address: String?
    var name: String?
    var phone: String?
    mutating func update(with contact: Contact) {
        address = contact.address ?? address
        name = contact.name ?? name
        phone = contact.phone ?? phone
    }
    var description: String {
        return "ID: \(id)\nName: \(name ?? "")\nPhone: \(phone ?? "")\nAddress: \(address ?? "")\n"
    }
}

游乐场测试:

let json1 = """
[{"id":"100", "name":"Matt", "phone":"0404040404", "address":"TBC"},
{"id":"110", "name":"Sean", "phone":"0404040404", "address":"TBC"},
{"id":"120", "name":"Luke", "phone":"0404040404", "address":"TBC"}]
"""

let json2 = """
[{"id":"100", "address":"1 Main Street"},
{"id":"110", "address":"2 Main Road"},
{"id":"120", "address":"3 Main Street"}]
"""

var contacts: [Contact] = []
var updates: [Contact] = []
do {
    contacts = try JSONDecoder().decode([Contact].self, from: Data(json1.utf8))
    updates = try JSONDecoder().decode([Contact].self, from: Data(json2.utf8))
    for contact in updates {
        if let index = contacts.index(where: {$0.id == contact.id}) {
            contacts[index].update(with: contact)
        } else {
            contacts.append(contact)
        }
    }
    let updatedJSON = try JSONEncoder().encode(contacts)
    print(String(data: updatedJSON, encoding: .utf8) ?? "")
} catch {
    print(error)
}

这将打印:

[{"id":"100","phone":"0404040404","name":"Matt","address":"1 主要 Street"},{"id":"110","phone":"0404040404","name":"Sean","address":"2 主要的 路"},{"id":"120","phone":"0404040404","name":"Luke","address":"3 大街"}]

【讨论】:

  • 我喜欢if let index = contacts.index(where: {$0.id == contact.id}) 的代码,我当然不会使用这种方法。
  • 我也会让联系人平等,但我想我会把这个任务留给 OP
  • 是的,最好让答案保持简单。它已经比 OP 要求的要多一些,尽管它确实展示了一些好的做法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-28
  • 1970-01-01
相关资源
最近更新 更多