3
struct Human{
    let name: String
    let id: String
    let travelled: String
}

struct Animal {
    let name: String
    let id: String
    let travelled: String
}

// Consider no human and animal object can have same name
let human1 = Human(name: "vikas", id: "12", travelled: "123")
let human2 = Human(name: "jacky", id: "15", travelled: "343")
let human3 = Human(name: "lucy", id: "32", travelled: "132")
let animal1 = Animal(name: "jacky", id: "56", travelled: "8979")
let animal2 = Animal(name: "lucy", id: "78", travelled: "678")
let animal3 = Animal(name: "jimmy", id: "98", travelled: "690")
let humans = [human1, human2, human3]
let animals = [animal1, animal2, animal3]

var list = [[String: String]]()
// can we eleminate this for loop with filter or something else
for human in humans {
    if let animal = animals.first(where: {$0.name == human.name}){
        let data = ["humanId": human.id, "animalId": animal.id]
        list.append(data)
    }
}
print(list)

Output:

[["humanId": "15", "animalId": "56"], ["humanId": "32", "animalId": "78"]]

Is there a way where we can apply multiple filter at a time to get the desired output Unable to find or create one

1
  • 2
    I think protocols can help you here, just create one with the 3 parameters you need, and implement it in both structs. Or change struct to class and use inheritance, and at the end the common data will be the base class. Commented Nov 7, 2019 at 9:16

3 Answers 3

3

You can try using compactMap(_:) instead.

let list = humans.compactMap { (human) -> [String:String]? in
    if let animal = animals.first(where: { $0.name == human.name }) {
        return ["humanId": human.id, "animalId": animal.id]
    }
    return nil
}
Sign up to request clarification or add additional context in comments.

Comments

1

This solutions still uses a loop but it will find multiple matches if such exists

animals.forEach {animal in
    let filtered = humans.filter { $0.name == animal.name }
        .map { human -> [String: String] in ["humanId": human.id, "animalId": animal.id] }

    list.append(contentsOf: filtered)
}

Comments

-1

Here it is

for index in 0..<humans.count {
    list[index]["humanId"] = humans[index]
    list[index]["animalId"] = animals[index]
}

2 Comments

Yes, it will crash. so can use min(humans.count, animals.count) or compare index with animals.count
And this does not answer the question as well.

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.