合并具有条件

时间:2016-10-26 13:32:22

标签: arrays swift function loops swift3

我想合并具有特定条件的两个数组并更新它们包含的对象。

首先是我在数组中的结构:

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]

我喜欢使用集合的zipmap函数来实现结果。结果是fisrtArray元素namesid更新。

示例: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不在同样的顺序。

3 个答案:

答案 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