🐾

【Rails】sort / sort_by メソッド

2023/07/07に公開

Sortメソッド

sortメソッドは、配列を昇順に並び替えるためのメソッドです。

要素の並び替えに<=>演算子(宇宙船演算子)を使用することができます。この演算子は、比較対象のオブジェクトを比較して、以下の3つの結果を返します。

  • 左辺が右辺より小さい場合は、-1を返す(左辺 < 右辺)。
  • 左辺が右辺と等しい場合は、0を返す(左辺 = 右辺)。
  • 左辺が右辺より大きい場合は、1を返す(左辺 > 右辺)。

以下は具体例です。

昇順

array = [3, 1, 2, 5, 4]
sorted_array = array.sort { |a, b| a <=> b }
puts sorted_array
# 出力: [1, 2, 3, 4, 5]

このコードは、1から5までの配列を、sortメソッドで昇順で並び替えています。ブロック内では<=>演算子を使い、要素aと要素bを比較しています。aがbより小さい場合に-1を、aとbが等しい場合に0を、aがbより大きい場合に1を返します。

計算結果:
計算結果は以下の通りです。

a b a <=> b (a > b)
3 1 1 true
3 2 1 true
3 5 -1 false
3 4 -1 false
1 2 -1 false
1 5 -1 false
1 4 -1 false
2 5 -1 false
2 4 -1 false
5 4 1 true

最終的には、各数値の大小関係に基づいて昇順にソートされ、結果として[1, 2, 3, 4, 5]という昇順にソートされた配列となります。


降順

array = [3, 1, 2, 5, 4]
sorted_array = array.sort { |a, b| b <=> a }
puts sorted_array
# 出力: [5, 4, 3, 2, 1]

このコードは、1から5までの配列を、sortメソッドにブロックを指定して降順で並び替えています。ブロック内では<=>演算子を使い、要素bと要素aを比較しています。bがaより小さい場合に-1を、bとaが等しい場合に0を、bがaより大きい場合に1を返します。

計算結果:
計算結果は以下の通りです。

a b b <=> a (b > a)
3 1 -1 false
3 2 -1 false
3 5 1 true
3 4 1 true
1 2 1 true
1 5 1 true
1 4 1 true
2 5 1 true
2 4 1 true
5 4 -1 false

上述から降順にソートされ、結果として[5, 4, 3, 2, 1]という降順にソートされた配列となります。

sort_byメソッド

sort_byメソッドは、ソートの基準を自由に指定し、配列をソートするためのメソッドです。

昇順

array = [3, 1, 2, 5, 4]
sorted_array = array.sort_by { |a| a }
puts sorted_array
# 出力: [1, 2, 3, 4, 5]

配列 array の要素を順番に取り出し、ブロック内の処理を行います。ブロック内の |a| の部分は要素を受け取るための変数であり、ここでは array の要素が a に代入されます。

ブロック内の処理は、要素 a をそのまま返すという意味です。つまり、要素の値そのものがソートの基準として使用されます。ブロック内で要素の値をそのまま返しているため、各要素の値同士が比較されて昇順にソートされます。

つまり、要素の値そのものに基づいて昇順にソートされるという仕組みです。

降順

降順の場合は、sort_byメソッドにマイナス(-)を使用して要素の値を反転させます。

array = [3, 1, 2, 5, 4]
sorted_array = array.sort_by { |a| -a }
puts sorted_array
# 出力: [5, 4, 3, 2, 1]

sort_byの他の例は以下の通りです。

文字列の長さでソート

array = ["apple", "banana", "cherry", "date"]
sorted_array = array.sort_by { |fruit| fruit.length }
puts sorted_array
# 出力: ["date", "apple", "cherry", "banana"]

この例では、配列 array の各要素は文字列です。ブロック内で要素の長さ fruit.length を返しています。したがって、文字列の長さがソートの基準となり、文字列の長さが短い順に出力されます。

ハッシュの特定のキーでソートする

array = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Charlie", age: 20 }
]
sorted_array = array.sort_by { |person| person[:age] }
puts sorted_array
# 出力: [
#   { name: "Charlie", age: 20 },
#   { name: "Alice", age: 25 },
#   { name: "Bob", age: 30 }
# ]

この例では、配列 array の各要素はハッシュ(キーと値がペア)です。ブロック内でハッシュの特定のキー person[:age]の値を返しています。したがって、ハッシュのageキーの値がソートの基準となり、ageキーの値が昇順に出力されます。

まとめ

sortは要素を直接比較して並び替える。
→要素が単純な値(文字列、数値など)の際に使用。

sort_byはブロック内の条件で並び替える。
→要素が複雑なもの、例えばハッシュのようなデータ構造で使用。

Discussion