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