Rubyのsortメソッドの使い方 | sort_byとの違いも解説

最終更新日:

この記事では、

    • Rubyでの基本的なSortメソッドの使い方
    • 配列やオブジェクトを含む複雑なデータ構造のソート方法
    • SortとSort_byメソッドを使い分けるコツ

    について現役Rubyエンジニアが解説していきたいと思います。

    著者:河合大

    DAI
    株式会社ワークスアプリケーションズにてQAエンジニア→株式会社AidemyにてAIプログラミングスクールのマーケティングを担当→キャリアコーチングサービスのパイオニアであるポジウィル株式会社にCMO就任→株式会社インディバースを創業。
    IT系キャリアに関して情報発信しているDAINOTEを運営。自身も自社プロダクトであるMedia Analyticsの開発をRuby on Railsで行うWebエンジニアである。本業はWebマーケター。最近は生成AI系の開発にどハマり中。著書は独学プログラマーのためのAIアプリ開発がわかる本 。詳細は運営者情報をご覧ください。 @never_be_a_pm

    配列の基本的なsort

    Rubyの配列をソートする場合、sortメソッドを使用します。

    このメソッドは、配列の要素を比較して、昇順に並び替えます。

    numbers = [5, 3, 8, 6, 1]
    sorted_numbers = numbers.sort
    puts sorted_numbers

    実行結果:

    [1, 3, 5, 6, 8]

    これが配列をソートする最も基本的な方法です。文字列も同様の方法でソートできます。

    文字列のソート方法

    文字列を含む配列をソートするには、同じくsortメソッドを利用します。

    words = ["banana", "apple", "cherry"]
    sorted_words = words.sort
    puts sorted_words

    実行結果:

    ["apple", "banana", "cherry"]

    文字列は辞書順にソートされます。

    配列内のオブジェクトをソート

    配列内にハッシュやオブジェクトが含まれる場合、sortメソッドをカスタマイズすることでソートできます。ブロックを使用して、特定の属性やキーに基づいてソートします。

    people = [{name: "John", age: 45}, {name: "Anna", age: 32}, {name: "Peter", age: 28}]
    sorted_people = people.sort_by { |person| person[:age] }
    puts sorted_people

    実行結果:

    [{:name=>"Peter", :age=>28}, {:name=>"Anna", :age=>32}, {:name=>"John", :age=>45}]

    この例では、人々を年齢で昇順にソートしています。

    関連:

    複数の条件でのソート方法

    sort_byメソッドは、複数の条件でソートするのにも便利です。例えば、名前でソートし、同じ名前の場合は年齢でソートしたい場合は次のようにします。

    people = [{name: "John", age: 45}, {name: "Anna", age: 32}, {name: "John", age: 28}]
    sorted_people = people.sort_by { |person| [person[:name], person[:age]] }
    puts sorted_people

    実行結果:

    [{:name=>"Anna", :age=>32}, {:name=>"John", :age=>28}, {:name=>"John", :age=>45}]

    名前で最初にソートし、それから年齢でソートしています。

    SortとSort_byメソッドの違い

    sortsort_byメソッドの違いを理解することは、Rubyでのソート操作において重要です。基本的に、sortメソッドはシンプルな配列のソートに適していますが、sort_byメソッドはより複雑なデータ構造のソートや、複数の条件に基づくソートに適しています。

    sortメソッドは、ブロックを利用して要素間の比較を行い、その結果に基づいて配列をソートします。

    numbers = [5, 3, 8, 6, 1]
    sorted_numbers = numbers.sort { |a, b| a <=> b }
    puts sorted_numbers

    実行結果:

    [1, 3, 5, 6, 8]

    一方、sort_byメソッドは、各要素から特定の属性や値を抽出し、それらを比較してソートする場合に適しています。例えば、オブジェクトの特定の属性に基づいてソートする場合などです。

    people = [{name: "John", age: 45}, {name: "Anna", age: 32}, {name: "Peter", age: 28}]
    sorted_people = people.sort_by { |person| person[:age] }
    puts sorted_people

    実行結果:

    [{:name=>"Peter", :age=>28}, {:name=>"Anna", :age=>32}, {:name=>"John", :age=>45}]

    Sortメソッドで降順に並び替える

    逆順ソートの基本

    sortメソッドを使って配列の要素を降順にソートするには、ブロック内の比較演算子の向きを変えるか、sortメソッド後にreverseメソッドをチェーンさせます。

    numbers = [5, 3, 8, 6, 1]
    desc_sorted_numbers = numbers.sort.reverse
    puts desc_sorted_numbers

    実行結果:

    [8, 6, 5, 3, 1]

    また

    numbers = [5, 3, 8, 6, 1]
    desc_sorted_numbers = numbers.sort { |a, b| b <=> a }
    puts desc_sorted_numbers

    実行結果:

    [8, 6, 5, 3, 1]

    このようにして、降順にソートします。

    Sort_byメソッドでハッシュをソート

    sort_byメソッドは、ハッシュやオブジェクトなどの構造化データをソートする際に非常に役立ちます。例えば、ハッシュのバリューに基づいてソートしたい場合は以下のようにします。

    # ハッシュをキーでソート
    h = { "banana" => 3, "apple" => 1, "cherry" => 2 }
    sorted_h = h.sort_by { |key, value| key }
    puts sorted_h

    実行結果:

    [["apple", 1], ["banana", 3], ["cherry", 2]]

    ハッシュをバリューでソート

    h = { "banana" => 3, "apple" => 1, "cherry" => 2 }
    sorted_h = h.sort_by { |key, value| value }
    puts sorted_h

    実行結果:

    [["apple", 1], ["cherry", 2], ["banana", 3]]

    このようにsort_byメソッドを利用することで、キーまたはバリューに基づくソートが容易になります。

    関連:【Ruby】 hashの使い方完全マニュアル | 追加, 更新, 削除, 高度な利用方法について現役エンジニアが解説します

    【Ruby】 hashの使い方完全マニュアル | 追加, 更新, 削除, 高度な利用方法について現役エンジニアが解説します

    破壊的メソッドと非破壊的メソッドの使い分け:sortとsort!

    Rubyでは、メソッド名に感嘆符!がつくメソッドは、その操作がオブジェクトを変更する「破壊的メソッド」であることを示します。sortメソッドにも破壊的なバージョンであるsort!が存在し、このメソッドは元の配列自体をソートして変更します。

    numbers = [5, 3, 8, 6, 1]
    numbers.sort!
    puts numbers

    実行結果:

    [1, 3, 5, 6, 8]

    非破壊的なsortメソッドの場合、ソートされた新しい配列が返されますが、元の配列は変更されません。これに対して、sort!メソッドは元の配列自体を変更します。

    <=>演算子の役割と比較方法

    sortsort_byメソッドでは、ブロックを使用することで、より複雑なソート処理を実装することが可能です。ブロック内で比較する要素を具体的に指定し、カスタマイズしたソート処理を実現できます。

    <=>演算子(スペースシップ演算子)は、ソート処理において重要な役割を担います。この演算子は、左のオペランドが右のオペランドより小さい時に-1、等しい時に0、大きい時に1を返します。これにより、sortメソッドのブロック内で要素同士を比較し、ソート順を決定します。

    words = ["banana", "apple", "cherry"]
    sorted_words = words.sort do |a, b|
    a.length <=> b.length
    end
    puts sorted_words

    実行結果:

    ["apple", "banana", "cherry"]

    このコードでは、文字列の長さを基準にソートしています。<=>演算子は、比較の結果に基づいて配列をソートする際に便利なツールです。

    複雑な配列のソート方法

    一次元配列と二次元配列のソート方法

    Rubyでは、単純な一次元配列だけでなく、二次元配列のソートも容易に行えます。二次元配列をソートする場合、sortまたはsort_byメソッドを使用し、ソートの基準となる要素をブロック内で指定します。

    array = [[2, 3], [1, 4], [3, 1]]
    sorted_array = array.sort_by { |element| element[0] }
    puts sorted_array.inspect

    実行結果:

    [[1, 4], [2, 3], [3, 1]]

    この例では、二次元配列の各要素(配列)の最初の数を基準にしてソートしています。sort_byメソッドを活用することで、複雑なデータ構造を持つ配列でも柔軟にソート処理を行うことが可能です。