13

この質問はおそらくかなりばかげていますが、私は例を見つけることができず、それを理解することもできません。

Person2つのクラスを姓、名、ミドルネームの順に比較したいと思います。これを行うための頭の痛い方法は次のとおりです。

def compare(that: Person): Int = {
  val last: Int = lastName.compare(that.lastName)
  if (last != 0) last
  else {
    val first: Int = firstName.compare(that.firstName)
    if (first != 0) first
    else middleName.compare(that.middleName)
}

これを行うにはもっと賢い方法があることは知っていますが(おそらくを使用してOrdering)、それに指を置くことはできません。

トッド

Orderingで正しいものにアクセスする方法を理解した後、これを理解しました。

def compare(that: Person): Int = {
  Ordering.Tuple3(Ordering.String, Ordering.String, Ordering.String).compare(
     (lastName, firstName, middleName),
     (that.lastName, that.firstName, that.middleName))
}

私はより少ない明示で逃げることができるとかなり確信していますが、これは機能し、適度にコンパクトです。

4

2 に答える 2

22

オプション1:sortBy

この方法を使用するsortByと、これは非常に簡単になります。

case class Person(first: String, middle: String, last: String)
val personList = List(Person("john", "a", "smith"), Person("steve", "x", "scott"), Person("bill", "w", "smith"))
personList.sortBy{ case Person(f,m,l) => (l,f,m) } 

オプション2:注文を延長[人]

を拡張することによりOrdered[Person]、クラスはそれ自体をソートする方法を知っているので、、、などsortedを無料で入手できます。minmax

case class Person(first: String, middle: String, last: String) extends Ordered[Person] {
  def compare(that: Person): Int =
    (last compare that.last) match {
      case 0 => 
        (first compare that.first) match {
          case 0 => middle compare that.middle
          case c => c
        }
      case c => c
    }
}

val personList = List(Person("john", "a", "smith"), Person("steve", "x", "scott"), Person("bill", "w", "smith"))
personList.sorted
personList.min
personList.max

オプション3:暗黙の注文

暗黙的な、を使用すると、元のクラスに特定の順序を関連付けることなく、、などを取得Orderingできます。このデカップリングは、特定のケースに応じて、便利な場合もあれば、煩わしい場合もあります。sortedmin

case class Person(first: String, middle: String, last: String)

implicit val ord = new Ordering[Person] { 
  def compare(self: Person, that: Person): Int =
    (self.last compare that.last) match {
      case 0 => 
        (self.first compare that.first) match {
          case 0 => self.middle compare that.middle
          case c => c
        }
      case c => c
    }
}

val personList = List(Person("john", "a", "smith"), Person("steve", "x", "scott"), Person("bill", "w", "smith"))
personList.sorted
personList.min
personList.max
于 2012-05-15T14:19:17.720 に答える
4

Scala 2.13+を使用している場合は、Ordering.byとを使用できますorElseBy。それは非常に明白です。

case class Person(first: String, middle: String, last: String)

implicit val ordering: Ordering[Person] = Ordering.by[Person, String](_.first)
   .orElseBy(_.middle)
   .orElseBy(_.last)

val list = List(Person("john", "a", "smith"), Person("steve", "x", "scott"), Person("bill", "w", "smith"))

list.sorted

于 2020-07-29T14:06:49.800 に答える