比较scala中的两个案例类实例

比较scala中的两个案例类实例,scala,Scala,我有一个案例课,比如说 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

我有一个案例课,比如说 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类的实例,比如name和age
如果我发现任何重复项,请删除任何重复项?

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


Scala 2.13.x之前的版本

如果没有
distinctBy()
我可能会折叠
列表来构建结果

....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))
或者您可以覆盖
Person
equals
hashCode
方法,但要小心,这会改变整个程序的
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))

谢谢。它很脆而且工作得很好。你知道如何在scala 2.12或2.11的较低版本中做到这一点吗?
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))