Given two lists of case classes
case class Entity(field1: String, field2: String, field3: String)
val a: Seq[Entity] = ...
val b: Seq[Entity] = ...
How to find all entities in a that's not in b, based on only field1 and field2, ignoring field3?
I've considered overriding the equals() function for the case class, also the neat trick of case class ()(ignored fields goes here) approach, but there will need to be multiple combinations of these fields needed for different use cases, e.g. diff using field1 + field2, then using field 1 + field 3, etc...
With ints, instead of String, for easy testing:
def similar (e: Entity, f: Entity) = { e.field1 == f.field1 && e.field2 == f.field2 }
scala> a
res60: Seq[Entity] = List(Entity(1,2,3), Entity(1,3,4), Entity(4,6,8), Entity(3,4,5))
scala> b
res61: Seq[Entity] = List(Entity(1,3,5), Entity(4,6,8), Entity(4,9,25))
scala> a.filter (aa => {! b.exists {bb => similar (aa, bb)} })
res62: Seq[Entity] = List(Entity(1,2,3), Entity(3,4,5))
val bad = b.iterator.map { x => x.field1 -> x.field2 }.toSet
val filtered = a.filterNot { x => bad(x.field1 -> x.field2) }
You can filter a
with specific condition using !b.exists()
:
case class Entity(field1: String, field2: String, field3: String)
val a = Seq(Entity("1", "p", "x"), Entity("2", "q", "y"), Entity("3", "r", "z"))
val b = Seq(Entity("1", "p", "x"), Entity("2", "q", "x"), Entity("3", "s", "z"))
a.filter( elA =>
!b.exists(elB => elB.field1 == elA.field1 && elB.field2 == elA.field2)
)
// res1: Seq[Entity] = List(Entity(3,r,z))
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