0

I have successfully created the following graph:

trait VertexProperty
case class ShopperProperty(memberID: String) extends VertexProperty
case class BasketProperty(basketID: String, epochDate: Long) extends VertexProperty

val vertices: Seq[(VertexId, VertexProperty)] = Seq(
  VertexId(1) -> ShopperProperty("shopper1"),
  VertexId(2) -> BasketProperty("basket1", 1398900001),
  VertexId(3) -> BasketProperty("basket2", 1390000000))

My question is, how do I filter on these vertex properties when they are case classes? For example, if I wanted to filter on the vertices which have the BasketProperty case class as their vertex property with Epoch date's that are greater than 1398900000, how would I do that?

I have been trying to use something like this:

vertices.filter{case (id,classthing) => classthing.BasketProperty.epoch > 1398900000}.count

But it is obviously incorrect as BasketProperty is not a member of classthing. However, I don't know how to proceed.

eliasah
  • 39,588
  • 11
  • 124
  • 154
Christopher Mills
  • 711
  • 10
  • 28

1 Answers1

1

Being case classes, you should be able to use .unapply() to destruct and match the class too, so you can use a more complete case like this:

val filteredVertices = vertices.filter {
  case (id, BasketProperty(uuid, epoch)) => epoch > 1398900000
  case _ => false
}
println(filteredVertices)

This prints:

List((VertexId(2),BasketProperty(basket1,1398900001)))

So we correctly matched both the type and the condition on epoch. Note that we had to add the default case _ => false since filter expects a complete function that maps every value to true/false rather than a partial function (there should be an overload IMHO).

Daniel Langdon
  • 5,899
  • 4
  • 28
  • 48
  • I ran the following for your first suggestion: graph.vertices.filter{ case (id, BasketProperty(uuid, epoch)) => epoch > 1398900000 }.count... but it didn't like the fact that there are also ShopperProperties in the graph and gave this match error: scala.MatchError: (384,ShopperProperty(0DF1C6CB-8F86-E411-9C64-74D02B10A4B6)) (of class scala.Tuple2). Why would it give a match error for something that is not a match when we have only asked it for things that are a match? – Christopher Mills Nov 04 '15 at 05:38
  • If I run the second options: graph.vertices.filter{ case (id, classthing) => classthing match { case BasketProperty(uuid, epoch) if epoch > 1398900000 => println("Gotit") case _ => println("Nope") }}... it complains that the case is not boolean: error: type mismatch; found : Unit required: Boolean case BasketProperty(uuid, epoch) if epoch > 1398900000 => println("Gotit") – Christopher Mills Nov 04 '15 at 06:03
  • Ok, the first one is my mistake, I missremembered and filter can't take a partial function (`collect` on collections does), so you need to provide a default case. In other words, filter needs to know if he keeps a given object, by receiving true/false (and does not assume false). The second version I mentioned does work, but you broke it by replacing true/false with print statements, which return nothing (Unit) rather than Boolean, hence the problem. – Daniel Langdon Nov 04 '15 at 13:51