I want to loop over the elements of a queue, and r...
# announcements
l
I want to loop over the elements of a queue, and remove them in the process. is there a fancy way to achieve this with
for (x in y)
or do i have to remove them manually ?
d
You probably don't want to modify a list you are iterating 🙂
l
why not ?
d
d
Copy code
val collection = mutableListOf(1, 2, 3)
val iterator = collection.iterator()
for (element in iterator) {
    if (element % 2 == 0) {
        iterator.remove()
    }
}
👍 1
f
to avoid collateral damage, if other function is reading or working with that list, you are going to have inconsistencies
l
@FranSoto that's because of mutability in general, not mutating while iterating specifically
d
I just invented a queue interface here but is this too manual? 🙂
Copy code
while (!queue.isEmpty()) {
val item = queue.pop();
// do stufff
}
l
its not that bad, it just seemed like a code smell. usually there is fancy ways to achieve stuff like this, but guess not this time
right now i am using
Copy code
for (element in collection) {
    collection.remove()
    //do sth
}
but it seems fishy somehow
d
Looks like SO issue I linked to
l
well then it would be
Copy code
val iterator = collection.iterator()
for (element in iterator) {
    iterator.remove()
    //do sth
}
i still get the impression that there's gotta be a better way to do this
f
if you need to remove each element before to proccess it, it's ok. Shouldn't be fancy
c
Why don't you use something like mapNotNull to create a new list without the items you don't want, or simply filter if you don't need to change any of them?
j
If this was Java, I'd use a ConcurrentLinkedQueue and repeatedly call
poll()
inside a while loop. In Kotlin, I'd avoid the use of mutable collections. Depends on the usecase.
l
I have a queue of user input parameters. I want to parse them 1 by 1 until a parameter matches a certain condition, at which point i will break out of the loop
d
You could make a custom
Iterable.removingForEach { ... }
extension method that does this. I don't believe any existing stdlib method will accomplish this. Java 8 has
removeIf
, but it won't be inlined, and you don't need the extra conditional evaluation of
removeIf { true }
d
removeIf
also has no guarantees about visiting each element only once and no guarantees about visiting them in order. The predicate you give it should be a pure function
j
Ok the queue was throwing me off, just use
dropWhile()
and pass it the inverse of your condition.
d
dropWhile
will not modify the original queue, it will create a new list containing the elements that were not removed.
367 Views