Ruby 配列のソート:sort と sort_by の使い分け

スポンサーリンク

Ruby 配列のソート:sort と sort_by の使い分け

Ruby で配列を並べ替えるには sortsort_by を使います。単純な並べ替えは sort、オブジェクトの特定の値でソートするなら sort_by が便利です。


早わかりまとめ

メソッド 向いている用途
sort 要素を直接比較してソート
sort_by 特定の値を基準にソート
reverse 逆順に並べ替える
min / max 最小・最大の要素を取り出す
min_by / max_by 特定の値で最小・最大を取り出す

sort:基本のソート

numbers = [3, 1, 4, 1, 5, 9, 2, 6]
p numbers.sort
# [1, 1, 2, 3, 4, 5, 6, 9]

words = ['banana', 'apple', 'cherry']
p words.sort
# ['apple', 'banana', 'cherry']

sort はブロックを渡すことで比較方法をカスタマイズできます。

# 降順
p numbers.sort { |a, b| b <=> a }
# [9, 6, 5, 4, 3, 2, 1, 1]

<=> 演算子は a < b なら -1a == b なら 0a > b なら 1 を返します。


sort_by:特定の値でソートする

オブジェクトの配列をソートするときは sort_by が簡潔です。

users = [
  { name: 'Carol', age: 20 },
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
]

# 年齢の昇順
by_age = users.sort_by { |user| user[:age] }
p by_age
# [{ name: 'Carol', age: 20 }, { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }]

# 名前のアルファベット順
by_name = users.sort_by { |user| user[:name] }
p by_name
# [{ name: 'Alice', ... }, { name: 'Bob', ... }, { name: 'Carol', ... }]

降順にソートする

numbers = [3, 1, 4, 1, 5, 9]

# 方法①:sort.reverse
p numbers.sort.reverse
# [9, 5, 4, 3, 1, 1]

# 方法②:sort_by でマイナスを使う(数値のとき)
p numbers.sort_by { |n| -n }
# [9, 5, 4, 3, 1, 1]

# 方法③:sort_by(...).reverse
users.sort_by { |u| u[:age] }.reverse

複数条件でソートする

ブロックに配列を返すと複数条件でソートできます。

users = [
  { name: 'Alice', score: 80 },
  { name: 'Bob', score: 90 },
  { name: 'Carol', score: 80 },
]

# スコア降順、同スコアなら名前昇順
sorted = users.sort_by { |u| [-u[:score], u[:name]] }
p sorted
# [{ name: 'Bob', score: 90 }, { name: 'Alice', score: 80 }, { name: 'Carol', score: 80 }]

破壊的メソッド:sort!

sort! は元の配列自体を書き換えます。

numbers = [3, 1, 4, 1, 5]
numbers.sort!
p numbers # [1, 1, 3, 4, 5](元の配列が変わる)

元の配列を保持したい場合は sort(非破壊的)を使います。


min / max / min_by / max_by

ソートせずに最小・最大だけ取り出す場合はこちらの方が効率的です。

numbers = [3, 1, 4, 1, 5, 9]

p numbers.min # 1
p numbers.max # 9

users = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 20 }]
p users.min_by { |u| u[:age] } # { name: 'Bob', age: 20 }
p users.max_by { |u| u[:age] } # { name: 'Alice', age: 25 }

まとめ

したいこと 使うもの
要素を昇順に並べる sort
特定の値を基準にソート sort_by
降順にする .reverse または sort_by { -n }
複数条件でソート sort_by { [key1, key2] }
最小・最大の要素を取り出す min_by / max_by

配列の絞り込みは「Ruby 配列の絞り込み:select・reject・find の使い方」を参照してください。

配列の変換・集計は「Ruby 配列の変換・集計:map・inject・flat_map の使い方」を参照してください。