我想合并具有特定条件的两个数组并更新它们包含的对象。
首先是我在数组中的结构:
struct Item {
var id:Int
var name:String
var value:Int
}
两个数组的第二个元素:
let fisrt = Item(id: 1, name: "Oleg", value: 3)
let second = Item(id: 2, name: "Olexander", value:5)
let fisrtInSecond = Item(id: 1, name: "Bogdan", value: 6)
let secondInSecond = Item(id: 2, name: "Max", value: 9)
阵列:
var fisrtArray = [fisrt, second]
let secondArray = [fisrtInSecond, secondInSecond]
我喜欢使用集合的zip
和map
函数来实现结果。结果是fisrtArray
元素names
由id
更新。
示例:fisrtArray = [Item(id: 1, name: "Bogdan", value:3), Item(id: 2, name: "Max", value:5)]
我知道如何通过简单的循环来做到这一点。但我正在寻找功能编程的更高级用法是Swift。
我的实验:
fisrtArray = zip(fisrtArray, secondArray).map()
主要问题我不知道如何在map
函数中写条件。条件应该是:
if ($0.id == $1.id) {
$0.name = $1.name
}
从评论讨论中可以突出显示zip
在我的情况下不合适,因为我们应该迭代所有数组以查找我们是否有类似的ID不在同样的顺序。
答案 0 :(得分:6)
以下代码根据2个数组中元素的顺序独立工作
firstArray = firstArray.map { (item) -> Item in
guard
let index = secondArray.index(where: { $0.id == item.id })
else { return item }
var item = item
item.name = secondArray[index].name
return item
}
“[Item(id:1,name:”Bogdan“,value:3),Item(id:2,name:”Max“,value:5)] \ n”
以下版本使用first(where:
Martin R.
方法
firstArray = firstArray.map { item -> Item in
guard let secondElm = secondArray.first(where: { $0.id == item.id }) else { return item }
var item = item
item.name = secondElm.name
return item
}
答案 1 :(得分:1)
上述特定问题的解决方案是:
struct Item {
var id: Int
var name: String
}
let first = Item(id: 1, name: "Oleg")
let second = Item(id: 2, name: "Olexander")
let firstInSecond = Item(id: 1, name: "Bogdan")
let secondInSecond = Item(id: 2, name: "Max")
let ret = zip([first, second], [firstInSecond, secondInSecond]).map({
return $0.id == $1.id ? $1 : $0
})
=>但是它要求第一个中的项目与第二个数组中的项目一样多 - 并且它们在相同的顺序中具有相同的ID ...
答案 2 :(得分:1)
map
函数不能直接改变其元素。而且由于你正在使用结构(通过值传递),它无论如何都无法工作,因为你在$ 0中看到的版本将是与数组中的版本不同的实例。要正确使用map
,我会使用这样的闭包:
fisrtArray = zip(fisrtArray, secondArray).map() {
return Item(id: $0.id, name: $1.name, value: $0.value)
}
这会产生您期望的结果。
现在,如果你的结构是对象(值类型而不是引用类型),你可以使用forEach
并在那里执行$0.name = $1.name
。