I have two collections of animals. I want to delete from Animal1 any components that are absent from Animal2.
struct Animal: Equatable{
var name: String
var type: String
static func ==(lhs: Animal, rhs: Animal) -> Bool {
return
lhs.name == rhs.name &&
lhs.type == rhs.type
}
}
var animal1 = Animal(name: "tiger", type: "wild")
var animal2 = Animal(name: "bear", type: "wild")
var animal3 = Animal(name: "elephant", type: "wild")
var animal4 = Animal(name: "lion", type: "wild")
var animal5 = Animal(name: "cow", type: "domestic")
var animal6 = Animal(name: "goat", type: "domestic")
var animal7 = Animal(name: "cat", type: "domestic")
var animal8 = Animal(name: "dog", type: "domestic")
var AnimalList1 = [animal1, animal2, animal3, animal5, animal6, animal8]
let AnimalList2 = [animal3, animal4, animal6, animal7, animal8]
The result array should be
[animal1, animal2, animal5]
My code
AnimalList2.forEach { deletedAnimal in
let animalTobeDeleted = AnimalList1.filter{$0.name != deletedAnimal.name}
}
But I am getting a different result
>Solution :
I think the problem lies in the code inside your filter:
AnimalList2.forEach { deletedAnimal in
let animalTobeDeleted = AnimalList1.filter{$0.name != deletedAnimal.name}
}
You are iterating over all the animals in the animals2 list, and for each animal object there, you are getting back all the animals that do not match it in animals2 list.
For example, the first animal in the animals2 list is:
var animal3 = Animal(name: "elephant", type: "wild")
Therefore, the result of running the code in the forEach clause will yield:
let animalTobeDeleted = AnimalList1.filter{$0.name != deletedAnimal.name}
[main.Animal(name: "tiger", type: "wild"), main.Animal(name: "bear",
type: "wild"), main.Animal(name: "cow", type: "domestic"),
main.Animal(name: "goat", type: "domestic"), main.Animal(name: "dog",
type: "domestic")]
These are not the animals you want to delete (even though you named the variable as such).
These are all the animals that do not match the current candidate from the animals2 list.
You could change your logic to do the following:
AnimalList2.forEach { deletedAnimal in
let animalToSave = AnimalList1.filter{$0.name == deletedAnimal.name}
}
This way you are checking if an animal object in the animal2 list exists in the animal1 list. If so, you can save it. Because according to your definition:
I want to delete from Animal1 any components that are absent from
Animal2.
Another way to go about this will be to switch between the animals2 list and the animals1 list in the forEach clause:
AnimalList1.forEach { deletedAnimal in
let animalTobeDeleted = AnimalList2.filter{$0.name == deletedAnimal.name}
}
This way, if you get an empty list, you know the animal from the animal1list is absent from the animals2 list and therefore, can be deleted.
Obviously, these are only suggestions and you could go about doing things in a different manner, if you please.