2010-12-11 47 views
15

我有一個ListBuffer。我想刪除所有符合特定條件的元素。scala刪除(就位)符合條件的ListBuffer的所有元素

我可以遍歷它並刪除每個元素。但是斯卡拉怎麼說變更你正在迭代的列表呢?它會工作,還是會刪除錯誤的元素/不返回所有元素? (與REPL的快速嘗試表明是的,它會搞亂)

我可以重複調用find並刪除找到的元素,直到找不到更多,但這聽起來效率不高。

.filter將返回一個沒有元素的新的ListBuffer,但我想要做到這一點。

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

看起來很有希望,但我不能完全看到

我應該如何做到這一點如何在這裏使用它?

+0

另請參閱http://stackoverflow.com/questions/2803085/iterators-for-mutable-collections-in-scala – 2010-12-11 19:05:13

回答

5

你不能做到這一點有效,很遺憾。的--=(xs: TraversableOnce[A])的實現(在擴展形式;實際的代碼更緊湊)

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

這就像做一個在一個時間(即它的O(n*m)其中n是原始列表的長度和低效m是要刪除的項目數量)。

一般而言,可變集合沒有像不可變集合那樣充分且強大的一組方法。 (也就是說,他們擁有所有用於不可變集合的精彩方法,但他們自己的相對較少。)

所以,除非您要刪除很少的對象,否則您最好過濾列表以創建一個新的。

+3

「可變集合沒有像不可變集合那樣充分且強大的一套方法」。是。這太遺憾了。函數式編程可能很棒,但有時候一個可變的數據結構真的是我想要的,而對多表單操作的相對微薄的支持有點讓人失望 – 2010-12-12 09:33:17

6

你可以將二者結合起來,並做到以下幾點:

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

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

完美。可能是愚蠢的,但是這是如何起作用的?過濾器是否返回迭代器而不是列表?或者,TraversableOnce是否意味着一個列表就足夠了 - 作爲迭代器 - =? – 2010-12-11 18:56:40

+0

'TraversableOnce'比迭代器更普遍。它是'Traversable'(所有集合都是基於的)和'Iterator'的普通超類。 – 2010-12-11 19:09:24

+0

請參閱http://www.scala-lang.org/docu/files/collections-api/collections.html – 2010-12-11 19:09:42