scala ArrayBuffer 删除带有谓词的所有元素
Scala 在过滤不可变序列方面非常优雅:
var l = List(1,2,3,4,5,6)
l = l.filter(_%2==1)
但是如何使用像 ArrayBuffer 这样的可变集合来做到这一点? 我发现的只是删除单个元素或切片,或者从另一个序列中删除元素,但没有删除谓词给出的元素。
编辑: 我希望找到类似的东西:
trait Removable[A] extends Buffer[A]{
def removeIf(p: A => Boolean){
var it1 = 0
var it2 = 0
while(it2 < length){
if( p( this(it2) ) ){
it2 += 1;
}
else {
this(it1) = this(it2)
it1 += 1;
it2 += 1;
}
}
trimEnd(it2-it1)
}
}
它以线性时间进行过滤,并且可以混合到任何缓冲区中,但只有 ArrayBuffer 有意义,在 ListBuffers 上它会很慢,因为索引确实需要线性时间。
Scala is very elegant in filtering immutable sequences:
var l = List(1,2,3,4,5,6)
l = l.filter(_%2==1)
But how do I do this with a mutable collections like ArrayBuffer?
All I found is the removal of single elements or slices, or remove elements from another sequence, but nothing that removes elements given by a predicate.
Edit:
I was hoping to find something similar tho this:
trait Removable[A] extends Buffer[A]{
def removeIf(p: A => Boolean){
var it1 = 0
var it2 = 0
while(it2 < length){
if( p( this(it2) ) ){
it2 += 1;
}
else {
this(it1) = this(it2)
it1 += 1;
it2 += 1;
}
}
trimEnd(it2-it1)
}
}
this filters in linear time and can be mixed into any Buffer, but only ArrayBuffer makes sense, on ListBuffers it would be slow, because indexing does take linear time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我的猜测是,通过构建新的缓冲区进行过滤会更有效,因此您通常只使用
filter
并使用其结果。否则,您可以编写自己的就地过滤方法:My guess is that it's more efficient to filter by building a new buffer, so you would normally just use
filter
and use its result. Otherwise you can write your own in-place filter method:您可以对 ArrayBuffer 执行相同的操作。所有集合类都具有相同的可用方法。
You do it the same with
ArrayBuffer
. All collection classes have the same methods available.人们一直在讨论拥有一组通过执行突变来工作的方法,但想出一套好的通用方法却出人意料地困难,而且另一方面,对此的需求还不够。
There has been discussion about having a set of methods that work by performing mutation, but coming up with a good, generic set is surprisingly hard, and, on the other hand, there just hasn't been enough demand for it.
这对我有用,但只能使用clone(),因此仍然创建一个新的ArrayBuffer:-)
但更好的方法是创建一个仅包含您想要删除的元素的新数组(因此不复制整个缓冲区)并且然后删除它们:
This worked for me, but only with clone(), thus still making a new ArrayBuffer :-)
But better way would be to make a new array of only those elements, which you want to remove (thus not copying the whole buffer) and then remove them:
我想出了这个
I came up with this
通常
withFilter
就足够了,特别是如果 Buffer 最终被转换为不可变的结构。确实,它并没有真正删除元素,但至少它没有创建新的 ArrayBuffer 对象。Often
withFilter
is good enough, especially if the Buffer is converted to an immutable structure in the end. True, it doesn't really remove the elements, but at least it doesn't create a new ArrayBuffer object.