在两个字典数组中查找重复键以使用新数组字典更新旧数组字典

Posted

技术标签:

【中文标题】在两个字典数组中查找重复键以使用新数组字典更新旧数组字典【英文标题】:Find duplicate keys in Two Arrays of Dictionaries to update old Array dictionary with new Array dictionary 【发布时间】:2017-03-29 18:28:55 【问题描述】:

我想用新词典更新已保存的词典。如果不存在值,则需要将新值附加到字典中。还使用字典的新值更新旧的现有值。

我保存的旧字典数组:

 var savedDict = [
             ["id":"1","pic":"Alice.png","name":"Alice Smith","position":"Nurse"],
             ["id":"2","pic":"brad.png","name":"Brad Smith MD","position":"Primary Doctor"],
             ["id":"12","pic":"bob.png","name":"Bob Smith PhD","position":"Hospital Coordinator"],
            ]

新下载的字典数组:

let newDict =   [
             ["id":"1","pic":"alice.png","name":"Alice Smith","position":"Nurse"],
             ["id":"2","pic":"brad.png","name":"Brad Smith MD","position":"Primary Doctor"],
             ["id":"3","pic":"user.png","name":"Dr. Quam","position":"Immunologist"],
             ["id":"4","pic":"jennifer.jpg","name":"Jennifer Johnson","position":"Case Manager"],
             ["id":"5","pic":"user.png","name":"John Banks MD","position":"Cardiologist"],
             ["id":"6","pic":"tammie.png","name":"Tammie Summers","position":"Case Manager"]
            ]

我想: 1.将“Alice.png”更新为“alice.png”,“id”=1, 2.ignore "id" = 2 因为两个字典数组相同, 3. 将 newDict 中的所有新项目追加到 savedDict

最终的字典应该是:

 upToDateDict = [
             ["id":"1","pic":"alice.png","name":"Alice Smith","position":"Nurse"],
             ["id":"2","pic":"brad.png","name":"Brad Smith MD","position":"Primary Doctor"],
             ["id":"12","pic":"bob.png","name":"Bob Smith PhD","position":"Hospital Coordinator"],
             ["id":"3","pic":"user.png","name":"Dr. Quam","position":"Immunologist"],
             ["id":"4","pic":"jennifer.jpg","name":"Jennifer Johnson","position":"Case Manager"],
             ["id":"5","pic":"user.png","name":"John Banks MD","position":"Cardiologist"],
             ["id":"6","pic":"tammie.png","name":"Tammie Summers","position":"Case Manager"]
            ]

到目前为止我已经试过了:

 import UIKit
 import Foundation

 func arrayContains(array:[[String:String]], value:[String:String]) -> Bool 
     for item in array 
         if item == value 
             return true
         
     
     return false
 

 var upToDateDict = savedDict//Array<Dictionary<String,String>>()

 //Save all of the dictionaries from the 1st array (savedDict) that aren't in the 2nd array (newDict)
 for item in newDict 
     if !arrayContains(array: savedDict, value: item) 
         upToDateDict.append(item)
     
 

 print(upToDateDict)

 //find duplicate keys and check if need to update saved dict with new dict

 let key = "id"

 for dict1 in savedDict 
     if let value = dict1[key] 
         for dict2 in newDict 
             if dict2[key] == value  //if true duplicate "id" key's  found

                 if dict1 != dict2  //not duplicate for all keys, so update saved with new dictionary

                     print("found \(key):\(value) in both arrays")
                     print("dict1:\(dict1)")
                     print("dict2:\(dict2)")

                     savedDict[dict1] = dict2 //what I want to do but will not build 

                  else //all keys duplicate in dict1 and dict2

             
         
     
 

我只想用 new 覆盖这个字典,所以我将 ["id":"1","pic":"Alice.png"... 更新为 ["id":"1","pic": “alice.png”...但这不起作用:

 savedDict[dict1] = dict2 

【问题讨论】:

你应该创建自定义的Class 而不是这样的字典。之后一切都会容易得多。 自定义类会是什么样子? 检查我的答案 【参考方案1】:

你应该创造

class Employee 
    var id: String
    var pic: String
    var name: String
    var position: String

    init(id: String, pic: String, name: String, position: String) 
        self.id = id
        self.pic = pic
        self.name = name
        self.position = position
    

那么你就有了

var oldEmployes: [Employee] = [Employee(id: "1", pic: "pic.png", name: "Name", position: "Position"), 
                               Employee(id: "2", pic: "pic2.png", name: "Name2", position: "Position2")]
var newEmployes: [Employee] = [Employee(id: "2", pic: "pic21.png", name: "Name21", position: "Position2"), 
                               Employee(id: "3", pic: "pic3.png", name: "Name3", position: "Position3")]

更新数组做一些类似的事情(使用高级函数可以更美观,但我认为这样看起来很清楚)

for employee in newEmployes 
     var isNew = true
     for oldEmployee in oldEmployes 
           if oldEmployee.id == employee.id 
               oldEmployee.name = employee.name
               oldEmployee.pic = employee.pic
               oldEmployee.position = employee.position
               isNew = false
           
     
     if isNew 
         oldEmployes.append(employee)
     

【讨论】:

你应该使Employee符合compere协议,这样比较员工实例或将它们放入数组中会更容易 如果您决定将class 更改为struct,请小心,因为这样您就不能只更新oldEmployee 对象 - 因为struct 是按值处理的,而不是按引用处理的 谢谢,这看起来不错。你能告诉我一个如何用上面的数据初始化 oldEmployes 的例子吗? 该协议被命名为Equatable 我在第一条评论中提到(developer.apple.com/reference/swift/equatable) @Brian: 看看init(id: String, pic: String, name: String, position: String) 哪里可以let emp1 = Employee(id: "1", pic: "abc.jpg", name: "def", position: "efg")

以上是关于在两个字典数组中查找重复键以使用新数组字典更新旧数组字典的主要内容,如果未能解决你的问题,请参考以下文章

使用字节数组作为字典键[重复]

如何从IOS中的字典数组中删除重复性? [关闭]

如何根据密钥是否已存在更新我的字典? [重复]

在c#中找出一个数组中出现次数最多的元素,求各种方法,要详细的代码

遍历字典数组以查找值

Swift - 使用 swiftyJSON 根据字典中的值查找字典数组的索引