I am trying to remove classes with identical fields from a collection using foldLeft function in Scala.
For example, a Box class is defined as: class Box(color: String = "", size: Int = 0)
Let’s create a simple collection Seq(Box, Box, Box) and try to filter it by the size field.
val s = Seq(Box("green", 1), Box("blue", 1), Box("red", 3))
s.foldLeft(Seq(s.head)){ (boxes, nextBox) =>
if (boxes.last.size != nextBox.size) { // throws an exception
boxes :+ nextBox
} else {
boxes
}
}
The above code throws an exception: value size cannot be accessed as a member of Box.
The above code works fine with primitive types and for Seq(1, 1, 3) will produce 1, 3.
It doesn’t help if you explicitly tell the compiler (boxes: Seq[Box], nextBox: Box), it doesn’t help even if you cast the value returned by last to Box.
Can you please explain why?
>Solution :
The above code throws an exception: value size cannot be accessed as a member of Box.
Because Box doesn’t have any public field called size; it has a constructor parameter called size which is different.
You can fix that doing class Box(color: String = "", val size: Int = 0) to make the constructor argument a field; or by using a case class that does that for you (and much more).
PS: It doesn’t throw an exception, it fails with a compiler error; two very different things.
Also, what you are trying to do is just distinctBy; as I always say the Scaladoc is your friend.
final case class Box(color: String = "", size: Int = 0)
val result = boxes.distinctBy(_.size)
Since you seem very new to the language and with many basic errors / misconceptions I would advise you to pick some course or read a book about the language. Also, I would encourage you to join the Scala Discord server where you may ask questions and get more interactive help.