微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Scala中将模式匹配用于Ordered.compare

如何解决在Scala中将模式匹配用于Ordered.compare

| 我有以下Scala课程:
case class Person(firstName: String,lastName: String,age: Int)
    extends Ordered[Person] {
  def compare(that: Person): Int = {
    if (this.lastName < that.lastName) -1
    else if (this.lastName > that.lastName) 1
    else if (this.firstName < that.firstName) -1
    else if (this.firstName > that.firstName) 1
    else this.age compare that.age
  }
}
允许按lastName,firstName和age进行排序。 如何使用模式匹配编写此代码?我已经提出了以下建议,但是有更好的方法吗?
case class Person(firstName: String,age: Int)
    extends Ordered[Person] {
  def compare(that: Person): Int = {
    that match {
      case Person(_,thatLastName,_) if this.lastName < thatFile => -1
      case Person(_,_) if this.lastName > thatFile => 1

      case Person(thatFirstName,_,_) if this.firstName < thatFirstName => -1
      case Person(thatFirstName,_) if this.firstName > thatFirstName => 1

      case Person(_,thatAge) => this.age compare thatAge
    }
  }
}
更新:根据Landei的答案更改为使用
Ordering[A]
implicit val personordering = new Ordering[Person] {
  def compare(first: Person,second:Person): Int = {
    second match {
      case Person(_,_) if first.lastName < thatLastName => -1
      case Person(_,_) if first.lastName > thatLastName => 1

      case Person(thatFirstName,_) if first.firstName < thatFirstName => -1
      case Person(thatFirstName,_) if first.firstName > thatFirstName => 1

      case Person(_,thatAge) => first.age compare thatAge
    }
  }
}

case class Person(firstName: String,age: Int)
但是我只匹配
second
似乎很尴尬。如何使其更“优雅”?

解决方法

Scala中的首选方法是提供一个隐式的Ordering而不是Ordered,它更加灵活并且不会给继承带来麻烦。 关于模式匹配,我认为没有更好的方法,因为compare方法的结果是
Int
s,它们不能保证为-1,0,1。Haskell's解决方案可以返回“枚举”对象(LT, EQ,GT)更清晰,可与模式匹配,但出于兼容性原因,Scala似乎遵循了C ++ / Java传统。 当然,您可以推出自己的比较“框架”:
abstract sealed class CompResult(val toInt:Int) {
  def andThen(next: => CompResult): CompResult
}
case object LT extends CompResult(-1) {
 def andThen(next: => CompResult) = LT
}
case object EQ extends CompResult(0) {
  def andThen(next: => CompResult) = next
}
case object GT extends CompResult(1) {
  def andThen(next: => CompResult) = GT
}

implicit def int2Comp(n:Int) =
   if (n == 0) EQ else if (n < 0) LT else GT


((\"sdkfhs\" compareTo \"fldgkjdfl\"):CompResult) match {
  case LT => println(\"less\")
  case EQ => println(\"same\")
  case GT => println(\"more\")
}
您可以写:
case class Person(firstName: String,lastName: String,age: Int)
  extends Ordered[Person] {
  def compare(that: Person): Int = {
    (this.lastName compareTo that.lastName).
    andThen (this.firstName compareTo that.firstName).
    andThen (this.age compare that.age).toInt
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。