[解決済み] 単純な case class の順序を定義する簡単な慣用的方法
質問
scala の単純な case クラスのインスタンスのリストがあり、それらを予測可能な辞書順の順序で
list.sorted
を使用して、予測可能な辞書順で印刷したいのですが、 "No implicit Ordering defined for ..." と表示されます。
ケースクラスの辞書的順序付けを提供する暗黙の了解は存在しますか?
辞書式順序をケースクラスに混ぜる簡単な慣用句はありますか?
scala> case class A(tag:String, load:Int)
scala> val l = List(A("words",50),A("article",2),A("lines",7))
scala> l.sorted.foreach(println)
<console>:11: error: No implicit Ordering defined for A.
l.sorted.foreach(println)
^
ハック」では満足できない。
scala> l.map(_.toString).sorted.foreach(println)
A(article,2)
A(lines,7)
A(words,50)
どのように解決するのですか?
個人的に好きな方法は、タプルに対して提供されている暗黙の順序付けを利用することです。
case class A(tag: String, load: Int) extends Ordered[A] {
// Required as of Scala 2.11 for reasons unknown - the companion to Ordered
// should already be in implicit scope
import scala.math.Ordered.orderingToOrdered
def compare(that: A): Int = (this.tag, this.load) compare (that.tag, that.load)
}
これは
のコンパニオンが
Ordered
からの暗黙の変換を定義します。
Ordering[T]
から
Ordered[T]
を実装しているすべてのクラスのスコープである
Ordered
. 暗黙の
Ordering
のための
Tuple
からの変換を可能にします。
TupleN[...]
から
Ordered[TupleN[...]]
は、暗黙のうちに
Ordering[TN]
が存在する場合、すべての要素
T1, ..., TN
を持たないデータ型に対してソートを行うことは意味がないため、常にそうでなければなりません。
Ordering
.
タプルの暗黙の順序付けは、複合ソートキーを含むすべてのソートシナリオのためのものです。
as.sortBy(a => (a.tag, a.load))
この回答が好評だったので、私はそれを発展させ、以下のようなソリューションがある状況下ではエンタープライズグレード™と見なされる可能性があることを指摘したいと思います。
case class Employee(id: Int, firstName: String, lastName: String)
object Employee {
// Note that because `Ordering[A]` is not contravariant, the declaration
// must be type-parametrized in the event that you want the implicit
// ordering to apply to subclasses of `Employee`.
implicit def orderingByName[A <: Employee]: Ordering[A] =
Ordering.by(e => (e.lastName, e.firstName))
val orderingById: Ordering[Employee] = Ordering.by(e => e.id)
}
与えられた
es: SeqLike[Employee]
,
es.sorted()
は名前でソートされ
es.sorted(Employee.orderingById)
はidでソートします。これにはいくつかの利点があります。
- ソートは、目に見えるコード成果物として一箇所で定義されます。これは、多くのフィールドで複雑なソートを行っている場合に便利です。
-
scala ライブラリで実装されているソート機能のほとんどは
Ordering
のインスタンスを使っているので、順序を直接提供することで、ほとんどの場合、暗黙の変換が不要になります。
関連
-
[解決済み] Scalaのcase classとclassの違いは何ですか?
-
[解決済み] IntelliJ Scala Pluginのcase classのインデントが不合理
-
[解決済み] 述語で配列を2つに分割するには?
-
[解決済み] ネストした構造体をよりきれいに更新する方法
-
[解決済み] SBTが終了せずに実行を停止する
-
[解決済み] Scalaのパターンマッチはなぜ変数で機能しないのですか?
-
[解決済み] Scalaの配列の初期化
-
[解決済み] Scalaです。リスト[Future]からFuture[List]への変換は、失敗したFutureを無視する。
-
[解決済み] Scalaのリストを作成するための好ましい方法
-
[解決済み] private[this] vs private
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 述語で配列を2つに分割するには?
-
[解決済み] 依存するメソッドタイプの説得力のある使用例とは?
-
[解決済み] Scalaでは、'val a. = _' (アンダースコア)は具体的にどのような意味ですか?A = _' (アンダースコア)とはどういう意味ですか?
-
[解決済み] ネストした構造体をよりきれいに更新する方法
-
[解決済み] scalaの列挙を理解する
-
[解決済み] SBTが終了せずに実行を停止する
-
[解決済み] Scalaのパターンマッチはなぜ変数で機能しないのですか?
-
[解決済み] Scalaの配列の初期化
-
[解決済み] Scalaです。リスト[Future]からFuture[List]への変換は、失敗したFutureを無視する。
-
[解決済み] Scalaのリストを作成するための好ましい方法