Вот общий подход к задаче.
Идея состоит в том, чтобы найти общие элементы в обоих списках в соответствии с некоторыми пользовательскими функциями, а затем удалить их оба.
def removeCommon[A, B, K](as: List[A], bs: List[B])
(asKey: A => K)
(bsKey: B => K): (List[A], List[B]) = {
def removeDuplicates[V](commonKeys: Set[K], map: Map[K, List[V]]): List[V] =
map
.iterator
.collect {
case (key, value) if (!commonKeys.contains(key)) =>
value.head
}.toList
val asByKey = as.groupBy(asKey)
val bsByKey = bs.groupBy(bsKey)
val commonKeys = asByKey.keySet & bsByKey.keySet
val uniqueAs = removeDuplicates(commonKeys, asByKey)
val uniqueBs = removeDuplicates(commonKeys, bsByKey)
(uniqueAs, uniqueBs)
}
Какой выможно использовать как следующее:
final case class Type1(name:String, surname: String, address: Int)
final case class Type2(name:String, surname: String, address: Int, dummy: String)
val type1List = List(
Type1("name1","surname1", 1),
Type1("name2","surname2", 2),
Type1("name3","surname3", 3)
)
val type2List = List(
Type2("name1","surname1", 1, "blah"),
Type2("name2","surname2", 2, "blah"),
Type2("name4","surname4", 4, "blah")
)
val (uniqueType1List, uniqueType2List) =
removeCommon(type1List, type2List) { type1 =>
(type1.name, type1.surname, type1.address)
} { type2 =>
(type2.name, type2.surname, type2.address)
}
// uniqueType1List: List[Type1] = List(Type1("name3", "surname3", 3))
// uniqueType2List: List[Type2] = List(Type2("name4", "surname4", 4, "blah"))