Home > Blockchain >  How to remove element from iterator if condition depends on property of the object the iterator is b
How to remove element from iterator if condition depends on property of the object the iterator is b

Time:11-23

Let me elaborate:

I need to be able to iterate over a list of objects. Each of the objects has a property which is a list, and I have to check if that list contains any elements that are not in another list.

When I tried to do it by using nested for loops, it kept giving me concurrent modification exceptions, so I tried to use an iterator, but now I'm stuck, since if I make an iterator based on the list of objects, I can't access the individual object's properties to then iterate over.

Here's some example code of what I was trying to accomplish:

for (preference in preferencesWithRestaurant) {
    for (restaurantID in preference.restaurantIDs) {
        // One method I tried using
        preferencesWithRestaurant.removeIf{ !listOfIds.contains(restaurantID) }

        /* alternate method I tried using
        if (!listOfIds.contains(restaurantID)) {
            preferencesWithRestaurant.remove(preference)
        }
        */

    }
}

CodePudding user response:

If you can replace the value of preferencesWithRestaurant or store the result in another variable then you can filter it:

preferencesWithRestaurant = preferencesWithRestaurant.filter { preference ->
    preference.restaurantIDs.all { it in listOfIds }
}

Depending on the exact type of preferencesWithRestaurant you may need to convert it to the proper type, e.g. invoke toMutableList() at the end.

If you prefer to modify preferencesWithRestaurant in-place, then you can use retainAll() (thanks @Tenfour04):

preferencesWithRestaurant.retainAll { preference ->
    preference.restaurantIDs.all { it in listOfIds }
}

Alternatively, you can keep your original approach, but use a mutable iterator to remove an item while iterating:

val iter = preferencesWithRestaurant.listIterator()
for (preference in iter) {
    for (restaurantID in preference.restaurantIDs) {
        if (!listOfIds.contains(restaurantID)) {
            iter.remove()
            break
        }
    }
}
  • Related