Reputation: 330
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...
Upvotes: 6
Views: 2624
Reputation: 8227
Create an entity mapping class that is only interested in fields you want to do the comparison on:
class EntityMap1_2( e: Entity ) {
override def equals( o: Any ): Boolean = ???
override def hashCode: Int = ???
}
It defines equals
and hashCode
only in terms of fields 1 and 2. Then you can populate respective sets and find the differences.
Similarly with other combinations of fields.
Upvotes: 0
Reputation: 22449
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))
Upvotes: 2
Reputation: 36229
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))
Upvotes: 5
Reputation: 40500
val bad = b.iterator.map { x => x.field1 -> x.field2 }.toSet
val filtered = a.filterNot { x => bad(x.field1 -> x.field2) }
Upvotes: 2