Merge arrays with condition

后端 未结 3 2052
忘掉有多难
忘掉有多难 2021-01-20 02:30

I would like to merge two arrays with specific condition and update objects that they are containing.

First my struct that is in arrays:

struct Item          


        
相关标签:
3条回答
  • 2021-01-20 03:12

    The map function cannot directly mutate its elements. And since you're using structs (passed by value), it wouldn't work anyway, because the version you see in $0 would be a different instance than the one in the array. To use map correctly, I'd use a closure like this:

    fisrtArray = zip(fisrtArray, secondArray).map() {
       return Item(id: $0.id, name: $1.name, value: $0.value)
    }
    

    This produces the result you're expecting.

    Now, if your structs were objects (value types instead of reference types), you could use forEach and do the $0.name = $1.name in there.

    0 讨论(0)
  • 2021-01-20 03:13

    The following code does work independently by the order of the elements inside the 2 arrays

    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"

    Update

    The following version uses the first(where: method as suggested by 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
    }
    
    0 讨论(0)
  • 2021-01-20 03:17

    A solution for your specific problem above would be:

    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
    })
    

    => But it requires that there are as many items in the first as in the second array - and that they have both the same ids in the same order...

    0 讨论(0)
提交回复
热议问题