Ordering
の代わりに使用する方がよい場合がよくありOrdered
ます。Ordering
は型クラスであり、よりもはるかに柔軟ですOrdered
(Ordered
比較する型によって実装する必要があるためOrdering
ですが、これを外部で定義できます)。型の自然順序付け (既定のOrdering
インスタンス) を定義するには、コンパニオン オブジェクトで暗黙的な順序付け値を定義するだけです。
では、序文で十分です。良いことは、Ordering
タプルの暗黙的な順序付けがあるため、やりたいことを使用するのが非常に簡単であることです (タプル要素自体に順序付けがある場合)`:
object Foo {
implicit val FooOrdering = Ordering.by{ foo: Foo =>
(foo.length, foo.x, foo.y, foo.z)
}
}
Ordering
さらに、型クラスのインスタンスを持つ任意の値を値に変換する暗黙的な変換があるためOrdered
(「参考文献」を参照)、任意のインスタンスを自動的に)を予期する関数Ordered.orderingToOrdered
に渡すことができるようにするために特別なことは何もありません。Foo
Ordered[Foo]
更新:あなたの新しい質問について:
少し関連しています - 注文を作成する方法はありますか?
それを行う1つの方法は、タプルに基づいOrdering.by
てタプルに変換するのとほとんど同じテクニックを使用することですが、構成する順序を明示的に渡します。
val byXOrdering = Ordering.by{ foo: Foo => foo.x }
val byYOrdering = Ordering.by{ foo: Foo => foo.y }
val byZOrdering = Ordering.by{ foo: Foo => foo.z }
// Compose byXOrdering and byYOrdering:
val byXThenYOrdering = Ordering.by{ foo: Foo => (foo, foo) }(Ordering.Tuple2(byXOrdering, byYOrdering))
// Compose byXOrdering and byYOrdering and byZOrdering:
val byXThenYThenZOrdering = Ordering.by{ foo: Foo => (foo, foo, foo) }(Ordering.Tuple3(byXOrdering, byYOrdering, byZOrdering))
しかし、それは比較的「うるさい」です。標準ライブラリだけを使用してもこれ以上のものは見つからなかったので、実際には独自のヘルパーを使用することをお勧めします。
final class CompositeOrdering[T]( val ord1: Ordering[T], val ord2: Ordering[T] ) extends Ordering[T] {
def compare( x: T, y: T ) = {
val comp = ord1.compare( x, y )
if ( comp != 0 ) comp else ord2.compare( x, y )
}
}
object CompositeOrdering {
def apply[T]( orderings: Ordering[T] * ) = orderings reduceLeft (_ orElse _)
}
implicit class OrderingOps[T]( val ord: Ordering[T] ) extends AnyVal {
def orElse( ord2: Ordering[T] ) = new CompositeOrdering[T]( ord, ord2 )
}
次のように使用できます。
val byXOrdering = Ordering.by{ foo: Foo => foo.x }
val byYOrdering = Ordering.by{ foo: Foo => foo.y }
val byZOrdering = Ordering.by{ foo: Foo => foo.z }
// Compose byXOrdering and byYOrdering:
val byXThenYOrdering = byXOrdering orElse byYOrdering
// Compose byXOrdering and byYOrdering and byZOrdering:
val byXThenYThenZOrdering = byXOrdering orElse byYOrdering orElse byZOrdering
または、次のようにさらに簡単にします。
// Compose byXOrdering and byYOrdering:
val byXThenYOrdering = CompositeOrdering(byXOrdering, byYOrdering)
// Compose byXOrdering and byYOrdering and byZOrdering:
val byXThenYThenZOrdering = CompositeOrdering(byXOrdering, byYOrdering, byZOrdering)
CompositeOrdering.apply
Ordering.multipleBy
は基本的にあなたが質問で呼んだものです。