導入
<=>(宇宙船演算子)は、2つの値を比べて「小さい・等しい・大きい」を -1 / 0 / 1 で返す演算子です。並べ替え(ソート)の心臓部で、これが分かると自分の好きな順番で並べられるようになります。
説明
<=> は比較結果を数値で返します。
puts (5 <=> 2) # 1 (左が大きい)
puts (2 <=> 5) # -1 (左が小さい)
puts (3 <=> 3) # 0 (等しい)
sort はこの <=> を使って並べ替えます。ブロックで比較のしかたを指定すると、順番を自由に変えられます。
p [3, 1, 2].sort # [1, 2, 3](昇順)
p [3, 1, 2].sort { |a, b| b <=> a } # [3, 2, 1](降順:a と b を逆に比べる)
sort_by は「何を基準に並べるか」をブロックで返すだけで済み、読みやすくよく使われます。
p ["bb", "a", "ccc"].sort_by { |s| s.length } # ["a", "bb", "ccc"](長さ順)
users = [{ name: "太郎", age: 30 }, { name: "花子", age: 20 }]
p users.sort_by { |u| u[:age] }.map { |u| u[:name] } # ["花子", "太郎"](年齢順)
やってみよう
sort のブロックで昇順・降順を切り替えたり、sort_by の基準(長さ・年齢・絶対値など)をいろいろ変えて並び順の変化を確かめましょう。
演習
[5, 2, 8, 1] を sort_by で大きい順に並べ替え、p で表示してください([8, 5, 2, 1] になります)。
ヒント1を見る
sort_by { |n| -n } のように符号を反転させると降順になります。