func mergingModels() { struct FirstModel: Codable, CustomStringConvertible, Equatable { var id: Int? var date: String? var name: String? var description: String { return "FirstModel(id: \(id!), date: \(date!), name: \(name!)]" } static func ==(lhs: FirstModel, rhs: FirstModel) -> Bool { return lhs.id == rhs.id && lhs.date == rhs.date && lhs.name == rhs.name } } struct SecondModel: Codable, CustomStringConvertible, Equatable { var id: Int? var date: String? var age: Int? var position: String? var description: String { return "SecondModel(id: \(id!), date: \(date!), age: \(age!), position: \(position!)]" } static func ==(lhs: SecondModel, rhs: SecondModel) -> Bool { return lhs.id == rhs.id && lhs.date == rhs.date && lhs.age == rhs.age && lhs.position == rhs.position } } struct FinalModel: Codable, CustomStringConvertible, Equatable { var first:[FirstModel]? var second: SecondModel? var description: String { return "FinalModel(first: \(first)), second: \(second))]" } static func ==(lhs: FinalModel, rhs: FinalModel) -> Bool { return lhs.first == rhs.first && lhs.second == rhs.second } } // 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 exptectation = [ "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"))] ] ] // 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 = 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) //or print(output as NSDictionary), as sometimes I find it more readable, maybe Objective-C old habits print("output == exptectation \(output == exptectation)") //In case it's not equal, let's analyze a little more to see which one failed let keys = Set(output.keys).union(exptectation.keys) keys.forEach { let subEqual = output[$0] == exptectation[$0] if !subEqual { print("Diff between:") print(output[$0]) print(exptectation[$0]) } else { print("EQUALS for: \($0)") } } } mergingModels()