1

Suppose I have two array of same object type, Now I want to update all the elements of first array based on some key of another array. I want to update isSelected to true if myArray id ,matches with testArray id. I can ietrate through myArray using for loop and check every id which is found in the testArray and based on that index isSelected value can be updated. But I am wondering if I can use higher order function like contains or filter for this use case.

class MyObject
{
    var id: Int
    var isSelected:Bool?
    var value: String
}

var myArray = [{id: 1, isSelected: nil, value: abcd}, {id: 2, 
isSelected: nil, value: xyz}, {id: 3, isSelected: nil, value: hghghg} ]

var testArray = [{id: 1, isSelected: nil, value: abcd}, {id: 2, 
isSelected: nil, value: xyz}]

let resultArray = [{id: 1, isSelected: true, value: abcd}, {id: 2, 
isSelected: true, value: xyz}, {id: 3, isSelected: nil, value: hghghg}] 

3 Answers 3

5

You can try

let testArrIds = testArray.map { $0.id }
myArray.forEach { $0.isSelected =  testArrIds.contains($0.id) ? true : $0.isSelected  }

It can be 1 line but i don't want to map the ids every loop of forEach as it would be expensive

myArray.forEach { $0.isSelected =  testArray.map { $0.id }.contains($0.id) ? true : $0.isSelected  }
Sign up to request clarification or add additional context in comments.

4 Comments

Two line solution is perfect, thanks Mr Khan :) can you please explain this ? true : $0.isSelected
@Xcoder don't forget to add an init to your class or make all vars optional
read section Ternary Conditional Operator in docs.swift.org/swift-book/LanguageGuide/BasicOperators.html
Yes, I have already added the init, hanks for pointing it out btw.
1

the above solution works well for class objects but not for structs, we can do it the following way for structs if someone is specifically looking for that like me.

struct Tag {
    let title: String
    var isSelected: Bool = false
}

let fetched = array of tags fetched from server
let current = array of currently selected tags 

Now we want to update the tags from server to get selected using currently selected tags

let updatedTags = fetched.map { fetchedTag in
    var updatedTag = fetchedTag
    if current.map({ $0.title }).contains(updatedTag.title) {
        updatedTag.isSelected = true
    }
    return updatedTag
 }

Comments

0

I did some changes to your class and arrays to make the code work

class MyObject: CustomStringConvertible {
    var id: Int
    var isSelected:Bool?
    var value: String

    var description: String {
        return "\(id) \(value) \(isSelected ?? false)"
    }

    init(id: Int, value: String) {
        self.id = id
        self.value = value
    }
}

var myArray = [MyObject(id: 1, value: "abcd"), MyObject(id: 2, value: "xyz"), MyObject(id: 3, value: "hghghg") ]

var testArray = [MyObject(id: 1, value: "abcd"), MyObject(id: 2, value: "xyz")]

testArray.forEach( { myObject in
    if let first = myArray.first(where: { $0.id == myObject.id }) {
        first.isSelected = true
    }
})

print(myArray)

[1 abcd true, 2 xyz true, 3 hghghg false]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.