Using fold to sum List of object attributes
In this code, I am trying to double each value and then sum v:
case class s(v : Int)
val l = List(s(2) , s(3))
l.fold(0) ((_.v * 2) + (_.v * 2))
But I am getting the error:
value v is not a member of Any
How can I perform an operation on each attribute of an object in a List?
As other authors have pointed out, fold
expect a supertype battery for your class. The class itself is also a supertype for itself, so we can write
case class s(v : Int)
val l = List(s(2) , s(3))
l.fold(s(0)){case (acc, elem) => s((acc.v * 2) + (elem.v * 2))}.v
but it's really too hard. in this case simple:
l.map(_.v*2).sum
will be better.
The first element in the fold is the start element and you call 0.v
, also note that the signature is the signature def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
, this means it returns a type variable that is the supertype of the passed type parameter, use foldLeft
instead that allows you to construct a value that is a subtype :
l.foldLeft(0) ((acc, curr) => acc + (curr.v * 2))
I used acc
and curr
to better visualize what was happening inside the fold, this is a shorthand form:
l.foldLeft(0) (_ + _.v * 2)
You can't do what you want, as your accumulator fold
is of type Int
, not type s
. Execution _.v * 2
for Int
doesn't make sense.
You can either do foldLeft
(or foldRight
):
l.foldLeft(0)(_ + _.v * 2)
Or even easier, use map
and sum
:
l.map(_.v * 2).sum