Scala - 按字段子集区分两个案例类列表

时间:2018-02-06 20:40:30

标签: scala collections

给出两个案例类列表

case class Entity(field1: String, field2: String, field3: String)
val a: Seq[Entity] = ...
val b: Seq[Entity] = ...

如何仅根据field1和field2查找不在b中的所有实体,忽略field3?

我考虑过覆盖case类的equals()函数,也就是case class()(忽略字段在这里)方法的巧妙处理,但是需要多个这些字段的组合才能使用不同的用例,例如差异使用field1 + field2,然后使用字段1 +字段3等...

5 个答案:

答案 0 :(得分:3)

使用int而不是String,以便于测试:

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))

答案 1 :(得分:2)

  val bad = b.iterator.map { x => x.field1 -> x.field2 }.toSet
  val filtered = a.filterNot { x => bad(x.field1 -> x.field2) }

答案 2 :(得分:1)

您可以使用a

过滤具有特定条件的!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))

答案 3 :(得分:0)

创建一个实体映射类,它只对您要对其进行比较的字段感兴趣:

class EntityMap1_2( e: Entity ) {
  override def equals( o: Any ): Boolean = ???
  override def hashCode: Int = ???
}

它仅根据字段1和2定义equalshashCode。然后,您可以填充各自的集合并找出差异。

与其他领域组合类似。

答案 4 :(得分:-1)

你可以迭代它们:

for {
  x <- a
  y <- b
  if x.field1 != y.field1 && x.field2 != y.field2
} yield x