Rubyのsortメソッドの使い方 | sort_byとの違いも解説
この記事では、
- Rubyでの基本的なSortメソッドの使い方
- 配列やオブジェクトを含む複雑なデータ構造のソート方法
- SortとSort_byメソッドを使い分けるコツ
について現役Rubyエンジニアが解説していきたいと思います。
著者:河合大
IT系キャリアに関して情報発信しているDAINOTEを運営。自身も自社プロダクトであるMedia Analyticsの開発をRuby on Railsで行うWebエンジニアである。本業はWebマーケター。最近は生成AI系の開発にどハマり中。著書は独学プログラマーのためのAIアプリ開発がわかる本 。詳細は運営者情報をご覧ください。 @never_be_a_pm
目次 (PRも含まれます)
配列の基本的な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メソッドの違い
sort
とsort_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の使い方完全マニュアル | 追加, 更新, 削除, 高度な利用方法について現役エンジニアが解説します
破壊的メソッドと非破壊的メソッドの使い分け:sortとsort!
Rubyでは、メソッド名に感嘆符!
がつくメソッドは、その操作がオブジェクトを変更する「破壊的メソッド」であることを示します。sort
メソッドにも破壊的なバージョンであるsort!
が存在し、このメソッドは元の配列自体をソートして変更します。
numbers = [5, 3, 8, 6, 1]
numbers.sort!
puts numbers
実行結果:
[1, 3, 5, 6, 8]
非破壊的なsort
メソッドの場合、ソートされた新しい配列が返されますが、元の配列は変更されません。これに対して、sort!
メソッドは元の配列自体を変更します。
<=>演算子の役割と比較方法
sort
やsort_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
メソッドを活用することで、複雑なデータ構造を持つ配列でも柔軟にソート処理を行うことが可能です。