比较scala中的2个case类实例



我有一个case类,比如说Person(名称:String,年龄:Int,地址:String(和我有一个它的实例列表。

object HelloWorld {
def main(args: Array[String]) {
case class Person(name: String,age: Int,location :String)
val per1=Person("gaurav",21,"chennai")
val per2=Person("gaurav",21,"pune")

val per3=Person("sur",26,"delhi")

val lst=per1::per2::per3::Nil
}
}

我该如何仅在名称和年龄这两个字段上比较这个case类的实例如果我发现任何重复项,就删除吗?

如果使用Scala 2.13.x,则可以使用distinctBy()

List(Person("gaurav",21,"chennai")
,Person("gaurav",21,"pune")
,Person("sur",26,"delhi"))
.distinctBy(p => (p.name,p.age))
//res0: List[Person] = List(Person(gaurav,21,chennai), Person(sur,26,delhi))

Scala 2.13.x之前

如果没有distinctBy(),我可能会折叠List来构建结果。

....foldLeft((List.empty[Person],Set.empty[(String,Int)])){
case ((acc,seen), prsn@Person(nm,age,_)) => 
if (seen(nm -> age)) (acc, seen)
else (prsn::acc, seen+(nm -> age))
}._1.reverse
//same result

您只需使用一些缓存和foldLeft:

val (_, distinctLst) = lst.foldLeft(Set.empty[(String, Int)] -> Vector.empty[Person]){
case ((metPersons, persons), nextPerson) if metPersons.contains(nextPerson.name -> nextPerson.age) => metPersons -> persons
case ((metPersons, persons), nextPerson) => (metPersons + (nextPerson.name -> nextPerson.age)) -> (persons :+ nextPerson)
}
println(distinctLst.toList) // List(Person(gaurav,21,chennai), Person(sur,26,delhi))

或者您可以覆盖PersonequalshashCode方法,但要小心它会改变整个程序的Person行为。

case class Person(name: String, age: Int, location: String) {
override def equals(o: Any): Boolean =
o match {
case Person(n, a, _) => n == name && a == age
case _ => false
}
override def hashCode(): Int = (name -> age).hashCode()
}
val per1 = Person("gaurav", 21, "chennai")
val per2 = Person("gaurav", 21, "pune")
println(per1 == per1) // true
println(per1 == per2) // true
val per3 = Person("sur", 26, "delhi")
val lst = per1 :: per2 :: per3 :: Nil
println(lst.distinct) // List(Person(gaurav,21,chennai), Person(sur,26,delhi))

最新更新