1. 概要

並べ替えとは、データセットを基準に基づいて昇順または降順で並べ替えることです。

検索を簡単かつ効果的にするために非常に重要です。 私たちは毎日それを使用して、ウェブサイトで必要な電話番号や最も安い製品を見つけます。

以前のチュートリアルでは、Javaでの並べ替えについて説明しました。 今日は、Scalaでシーケンスをソートするためのさまざまなオプションを紹介します。

2. 例

次の例では、ユーザーのリストを並べ替えます。 それぞれに名前年齢があります。

case class User(name: String, age: Int)

val users = List(
  User("Mike", 43),
  User("Mike", 16),
  User("Kelly", 21)
)

3. 並べ替え

Ordering インスタンスに従ってアイテムを順番に並べ替える、専用のsortedメソッドがあります。

def sorted[B >: A](implicit ord: Ordering[B]): Repr

Reprは、要素を含む実際のコレクションのタイプです。 私たちの場合、それはリスト。 Aはコレクション内の要素のタイプです。 私たちの場合、それはユーザー。

ユーザーを並べ替えてみましょう:

users.sorted

実際には、Userに対して暗黙のOrderingが定義されていないため、コンパイルされません。 コンパイラを満足させるには、不足している暗黙のパラメータを指定する必要があります。

implicit val userOrdering: Ordering[User] = Ordering.by(_.age)

users.sorted shouldBe List(
  User("Mike", 16),
  User("Kelly", 21),
  User("Mike", 43)
)

現在、コンパイラは、usersを年齢別に並べ替えたいことを認識しています。 逆順を使用したい場合は、 Ordering:メソッドを使用できます。

implicit val userOrdering: Ordering[User] = Ordering.by[User, Int](_.age).reverse

users.sorted shouldBe List(
  User("Mike", 43),
  User("Kelly", 21),
  User("Mike", 16)
)

ソートされたコンパイルを作成する別の方法は、UserOrdered[User]から継承させることです。

case class User(name: String, age: Int) extends Ordered[User] {
    override def compare(that: User): Int =
      java.lang.Integer.compare(age, that.age)
}

users.sorted shouldBe List(
  User("Mike", 16),
  User("Kelly", 21),
  User("Mike", 43)
)

コンパイラがスコープ内のUserOrderingをどのように見つけることができるかを自問するかもしれません。 スコープで使用可能な暗黙の変換メソッドがあるため、これは機能します。 このメソッドは、java.lang.Comparableを拡張する任意のタイプに対してOrderingを返すことができます。

implicit def ordered[A <% Comparable[A]]: Ordering[A] = new Ordering[A] {
    def compare(x: A, y: A): Int = x compareTo y
}

したがって、Userには暗黙のOrderingがないため、コンパイラは Ordered[User]Ordering[User]に変換します。

注意深い読者はそれに気付くでしょう暗黙の変換方法には、Comparableではなく順序付けられました。 正しい! ただし、OrderedComparableを拡張しているため、問題なく動作しています。

trait Ordered[A] extends Any with java.lang.Comparable[A]

4. sortBy

特定のフィールドでデータを並べ替える場合は、スコープに Ordering フィールドタイプがある限り、sortByメソッドを使用できます。

def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Repr

usersを名前で並べ替えましょう。

users.sortBy(_.name) shouldBe List(
  User("Kelly", 21),
  User("Mike", 43),
  User("Mike", 16)
)

スコープでOrdering[String]を定義することを忘れなかったかどうかを尋ねる場合があります。 定義する必要はありません。 Scalaには、Char、Int、String、Booleanなどのすべてのデータ型の順序が事前定義されています。

Tuple には、事前定義された Ordering もあります。これにより、複数のフィールドでデータを並べ替えることができます。 これを使用して、ユーザー名前および年齢:で並べ替えます。

users.sortBy(u => (u.name, u.age)) shouldBe List(
  User("Kelly", 21),
  User("Mike", 16),
  User("Mike", 43)
)

5. sortWith

の順序付けを忘れたい場合は、 sortWith メソッドを使用できます。このメソッドは、指定された比較関数に従って要素を並べ替えます。

def sortWith(lt: (A, A) => Boolean): Repr

ユーザーを最も古いものから最も若いものへと並べ替えましょう。

users.sortWith(_.age > _.age) shouldBe List(
  User("Mike", 43),
  User("Kelly", 21),
  User("Mike", 16)
)

6. 結論

この短いチュートリアルでは、Scalaでデータを並べ替えるための3つの異なる方法を確認しました。 また、ソートの戦略を表す Ordering、についても学びました。

いつものように、記事の完全なソースコードは、GitHubから入手できます。