Reputation: 507
Hi I'm wordering how could I simplify code below:
val leavesValues: ListBuffer[Double] = ListBuffer()
leavesValues.appendAll(
leaves
.collect { case leaf: Leaf => leaf.value.toDouble }
.toList
)
leavesValues
I hope there is possibility to make this as oneliner.
Upvotes: 0
Views: 73
Reputation: 127791
You can use the to
generic conversion method (in Scala <2.13):
val leavesValues = leaves.collect {
case leaf: Leaf => leaf.value.toDouble
}.to[ListBuffer]
Using to
is similar to breakOut
, in the sense that it uses the CanBuildFrom
machinery to do the conversion, except here you can provide just the target collection type (without element type) directly to the method. Sadly, this does not work for maps because to
requires a type with one type argument (ListBuffer[A]
, Vector[A]
, etc), while all Map
descendants have two (HashMap[A, B]
, TreeMap[A, B]
, etc).
In Scala 2.13 with its new collections library this could be written as follows:
val leavesValues = leaves.collect {
case leaf: Leaf => leaf.value.toDouble
}.to(ListBuffer)
Note the round parentheses instead of brackets: in Scala 2.13, the to
method accepts a reference to a companion object of a collection rather than collection type. In Scala 2.13, the collection library has different design; in particular, this new approach allows for map types as well:
val map: Map[Int, Int] = List(1 -> 2, 3 -> 4).to(Map)
Upvotes: 0
Reputation: 40500
Why would you want it a ListBuffer
to begin with??? Mutable containers should be avoided, and in scala you almost never need them, except for some rare corner cases. I suggest, that you just pretend they don't exist at all until you get enough grasp of the language to be able to confidently distinguish those rare scenarios.
Having said that, conversion between collection types can be done without intermediaries using a thing called breakOut
. This is how you use it:
import scala.collection.breakOut
val leavesValues: ListBuffer[Double] = leaves.collect {
case leaf: Leaf => leaf.value.toDouble
}(breakOut)
Upvotes: 3
Reputation: 1756
Is following simple enough ?
val leavesValues: ListBuffer[Double] = ListBuffer(leaves.collect { case leaf: Leaf => leaf.value.toDouble } :_*)
If Leaf
is a case class:
val leavesValues: ListBuffer[Double] = ListBuffer(leaves.collect { case Leaf(value) => value.toDouble } :_*)
Upvotes: 2