如何在Swift中比较两个不相等的字典,然后将它们添加到一个新字典中?

ogsagwnx  于 2023-02-21  发布在  Swift
关注(0)|答案(1)|浏览(125)

我找到了一个similar question,但它不能应用于我的问题。
我有2个不相等的字典,想把它们合并成1个,我想我会用下面的例子来描述它:

struct FirstModel: Codable {
    var id: Int?
    var date: String?
    var name: String?
}

struct SecondModel: Codable {
    var id: Int?
    var date: String?
    var age: String?
    var position: String?
}

struct FinalModel: Codable {
    var first:[FirstModel]?
    var second: SecondModel?
}

// dict1: [date: [FirstModel]]
var dict1 = [
    "2023-02-19": [FirstModel(id: 10, date: "2023-02-19", name: "Harry"), FirstModel(id: 11, date: "2023-02-19", name: "John")],
    "2023-02-13": [FirstModel(id: 12, date: "2023-02-13", name: "Harry"), FirstModel(id: 11, date: "2023-02-13", name: "John")],
    "2023-02-12": [FirstModel(id: 13, date: "2023-02-12", name: "Harry"), FirstModel(id: 11, date: "2023-02-12", name: "John")],
    "2023-02-10": [FirstModel(id: 14, date: "2023-02-10", name: "Harry"), FirstModel(id: 11, date: "2023-02-10", name: "John")],
    ]

// dict1: [date: [SecondModel]]
var dict2 = [
    "2023-02-19": [SecondModel(id: 10, date: "2023-02-19", age: 12, position: "A"), SecondModel(id: 15, date: "2023-02-19", age: 12, position: "A")],
    "2023-02-09": [SecondModel(id: 20, date: "2023-02-09", age: 12, position: "A"), SecondModel(id: 17, date: "2023-02-09", age: 12, position: "A")],
    "2023-02-10": [SecondModel(id: 14, date: "2023-02-10", age: 12, position: "A"), SecondModel(id: 16, date: "2023-02-10", age: 12, position: "A")],
    "2023-02-12": [SecondModel(id: 27, date: "2023-02-12", age: 12, position: "A"), SecondModel(id: 11, date: "2023-02-12", age: 12, position: "A")],
    "2023-02-08": [SecondModel(id: 22, date: "2023-02-08", age: 12, position: "A"), SecondModel(id: 11, date: "2023-02-08", age: 12, position: "A")]
    ]

我想要一本这样的新字典

// newDict: [date: [id: [FinalModel]]]
var newDict = [
    "2023-02-08": [
        11: [FinalModel(first: nil, second: SecondModel(id: 11, date: "2023-02-08", age: 12, position: "A"))],
        22: [FinalModel(first: nil, second: SecondModel(id: 22, date: "2023-02-08", age: 12, position: "A"))]
        ],
    "2023-02-09": [
        17: [FinalModel(first: nil, second: SecondModel(id: 17, date: "2023-02-09", age: 12, position: "A"))],
        20: [FinalModel(first: nil, second: SecondModel(id: 20, date: "2023-02-09", age: 12, position: "A"))]
        ],
    "2023-02-10": [
        11: [FinalModel(first: [FirstModel(id: 11, date: "2023-02-10", name: "John")], second: nil)],
        14: [FinalModel(first: [FirstModel(id: 14, date: "2023-02-10", name: "Harry")], second: SecondModel(id: 14, date: "2023-02-10", age: 12, position: "A")],
        16: [FinalModel(first: nil, second: SecondModel(id: 16, date: "2023-02-10", age: 12, position: "A"))]
        ],
    "2023-02-12": [
        11: [FinalModel(first: [FirstModel(id: 11, date: "2023-02-12", name: "John")], second: SecondModel(id: 11, date: "2023-02-12", age: 12, position: "A"))],
        13: [FinalModel(first: [FirstModel(id: 13, date: "2023-02-12", name: "Harry")], second: nil)],
        27: [FinalModel(first: nil, second: SecondModel(id: 27, date: "2023-02-12", age: 12, position: "A"))]
        ],
    "2023-02-13": [
        11: [FinalModel(first: [FirstModel(id: 11, date: "2023-02-13", name: "John")], second: nil)],
        12: [FinalModel(first: [FirstModel(id: 12, date: "2023-02-13", name: "Harry")], second: nil)]
        ],
    "2023-02-19": [
        10: [FinalModel(first: [FirstModel(id: 10, date: "2023-02-19", name: "Harry")], second: SecondModel(id: 10, date: "2023-02-19", age: 12, position: "A"))],
        11: [FinalModel(first: [FirstModel(id: 11, date: "2023-02-19", name: "John")], second: nil)],
        15: [FinalModel(first: nil, second: SecondModel(id: 15, date: "2023-02-19", age: 12, position: "A")]
        ],
]

因此,对于每个date,有许多不同的id,每个id可以包含许多FirstModel,但只能包含SecondModel。我在比较和合并它们时遇到了一些问题,newdict是我想要显示的。
任何帮助都是非常感谢的。谢谢!
我想我找到了解决办法,但性能不是那么好。
步骤1:转换dict 1:[date: [FirstModel]] -> [date: [id: [FirstModel]]]
步骤2:转换dict 2:[date: [SecondModel]] -> [date: [id: [SecondModel]]]
步骤3:将dict 1和dict 2合并为:[date: FinalModel3(first: [id: [FirstModel]], second: [id: [SecondModel]])],暂时称为dict 3
步骤4:然后将dict 3转换为:[date: [id: FinalModel2(first: [FirstModel], second: [SecondModel])]]

chy5wohz

chy5wohz1#

这应该可以达到目的:

// Retrieve all dates
let allKeysDate = Set(dict1.keys).union(dict2.keys)

let output = allKeysDate.reduce(into: [String: [Int: [FinalModel]]]()) { partialOutput, currentDateKey in

    let firstModels: [FirstModel]? = dict1[currentDateKey]      //Get the firstModel for that date
    let secondModels: [SecondModel]? = dict2[currentDateKey]    //Get the SecondModel for that date
    //Get all ids for that date, depending on the ids of firstModels & secondModels
    let allIds: Set<Int> = Set(firstModels?.compactMap { $0.id } ?? []).union( secondModels?.compactMap { $0.id } ?? [])

    //Create models
    let models: [Int: [FinalModel]] = allIds.reduce(into: [Int: [FinalModel]]()) { partialModelResult, currentIdKey  in
        let first: [FirstModel] = firstModels?.filter { $0.id == currentIdKey } ?? [] //Get all FirstModel for that id
        let second: [SecondModel]? = secondModels?.filter { $0.id == currentIdKey } //Get all SecondtModel for that id

        //I supposed there can only be one SecondModel for each id (see `second?.first`), if not, you need to decide on the behavior
        let finalModel = FinalModel(first: first.isEmpty ? nil : first, second: second?.first)
        var currentlySaved = partialModelResult[currentIdKey, default: []]
        currentlySaved.append(finalModel)
        partialModelResult[currentIdKey] = currentlySaved
    }

    //Set the value for the currentDate
    partialOutput[currentDateKey] = models
}

print(output)

其思想是检索所有日期(allKeysDate),对其进行迭代(使用reduce(into:_)),并根据该日期中的每个id创建多个FinalModel
Full testable code

相关问题