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.
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:
def filterInPlace[A](b: collection.mutable.Buffer[A])(fun: A => Boolean): Unit = {
var sz = b.size
var i = 0; while(i < sz) {
if (fun(b(i))) {
i += 1
} else {
sz -= 1
b.remove(i)
}
}
}
val b = collection.mutable.ArrayBuffer((1 to 6): _ *)
filterInPlace(b)(_ % 2 == 1)
println(b)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With