Scala Удалить (на месте) все элементы ListBuffer, которые удовлетворяют условию
У меня есть ListBuffer. Я хочу удалить все элементы, удовлетворяющие определенному условию.
Я мог бы перебрать его и удалить каждый элемент. Но что do Scala говорит о том, что вы перебираете список, который вы повторяете? Будет ли он работать, или он удалит неправильные элементы/не вернет все элементы? (Быстрая попытка с REPL предполагает, что да, это испортится)
Я мог неоднократно называть find, а затем удалять найденный элемент, пока я больше не нахожу, но это звучит неэффективно.
.filter вернет мне новый ListBuffer без элементов, но я хочу сделать это на месте.
Это
def --= (xs: TraversableOnce[A]) : ListBuffer.this.type
Removes all elements produced by an iterator from this list buffer.
выглядит многообещающим, но я не могу понять, как его использовать здесь.
Как мне это сделать?
Ответы
Ответ 1
Вы не можете сделать это эффективно, к сожалению. Реализация --=(xs: TraversableOnce[A])
(в расширенной форме, фактический код более компактный)
xs foreach (x => this -= x) ; this
который так же неэффективен, как и один за раз (т.е. он O(n*m)
, где n
- это длина исходного списка, а m
- количество элементов для удаления).
В общем, изменчивые коллекции не обладают полным и мощным набором методов как непреложных. (То есть, у них есть все замечательные методы, используемые в неизменяемых коллекциях, но относительно немного их собственных.)
Поэтому, если вы не удаляете очень мало объектов, вам, вероятно, лучше фильтровать список, чтобы создать новый.
Ответ 2
Вы можете объединить два и сделать следующее:
val lb = ListBuffer(1,2,3,4,5,6)
lb --= lb.filter(_ % 2 == 0)
println(lb)
// outputs: ListBuffer(1, 3, 5)