scala Remove (in place) all elements of a ListBuffer that meet a condition

情到浓时终转凉″ 提交于 2019-12-12 07:44:05

问题


I have a ListBuffer. I want to remove all elements that meet a certain condition.

I could iterate over it and remove each element. But what doe Scala say about mutating a list that you are iterating over? Will it work, or will it delete the wrong elements/not return all elements? (A quick attempt with the REPL suggests that yes, it will mess up)

I could repeatedly call find and then remove the found element until I don't find any more, but that sounds inefficient.

.filter will return me a new ListBuffer without the elements, but I want to do it in place.

This

def --= (xs: TraversableOnce[A]) : ListBuffer.this.type
Removes all elements produced by an iterator from this list buffer.

looks promising but I can't quite see how to use it here

How should I do this?


回答1:


You can't do this efficiently, unfortunately. The implementation of --=(xs: TraversableOnce[A]) is (in expanded form; the actual code is more compact)

xs foreach (x => this -= x) ; this

which is just as inefficient as doing it one at a time (i.e. it's O(n*m) where n is the length of the original list and m is the number of items to remove).

In general, the mutable collections don't have as full and powerful a set of methods as the immutable ones. (That is, they have all the wonderful methods used on immutable collections, but relatively few of their own.)

So unless you're removing very few objects, you're probably better off filtering the list to create a new one.




回答2:


You could combine the two and do the following:

val lb = ListBuffer(1,2,3,4,5,6)
lb --= lb.filter(_ % 2 == 0)

println(lb)
// outputs: ListBuffer(1, 3, 5)


来源:https://stackoverflow.com/questions/4417994/scala-remove-in-place-all-elements-of-a-listbuffer-that-meet-a-condition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!