やりたいこと
配列の中に入っているハッシュの値が大きい順に並び替えたい。
[{:name=>"player1", :count=>21},
{:name=>"player2", :count=>0},
{:name=>"player3", :count=>30}]
このように並び替えたい。↓
[{:name=>"player3", :count=>30},
{:name=>"player1", :count=>21},
{:name=>"player2", :count=>0}, ]
考えたこと
「配列の要素を並び替えるのにsortメソッドというのがあったはず。sortメソッドを使えば並び替えられるかな」
試したこと
公式リファレンスをもとにsort
メソッドを使ってみる。
今回は各要素がハッシュの形をしており、:count
キーの値を比較する。
a = [{:name=>"player1", :count=>4},
{:name=>"player2", :count=>28},
{:name=>"player3", :count=>20},
{:name=>"player4", :count=>0}]
a.sort do |a, b|
a[:count] <=> b[:count]
end
:count
キーの値が小さい順に並び替えることができた。
=>
[{:name=>"player4", :count=>0},
{:name=>"player1", :count=>4},
{:name=>"player3", :count=>20},
{:name=>"player2", :count=>28}]
破壊的メソッドsort!
で配列そのものを並び替えたあと、reverse
メソッドを使うと大きい順に並び替えることができた。
irb(main):038* a.sort! do |a, b|
irb(main):039* a[:count] <=> b[:count]
irb(main):040> end
=>
[{:name=>"player4", :count=>0},
{:name=>"player1", :count=>4},
{:name=>"player3", :count=>20},
{:name=>"player2", :count=>28}]
irb(main):041> a.reverse
=>
[{:name=>"player2", :count=>28},
{:name=>"player3", :count=>20},
{:name=>"player1", :count=>4},
{:name=>"player4", :count=>0}]
失敗例1
reverse
メソッドをつなげて大きい順に並び替えようとするとできない。
a.sort.reverse do |a, b|
irb(main):029* a[:count] <=> b[:count]
irb(main):030> end
(irb):28:in `sort': comparison of Hash with Hash failed (ArgumentError)
失敗例2
sort_by
メソッドで同じことをやろうとするとできない。(sort_by!
メソッドでも同じ結果になる)
irb(main):046* a.sort_by do |a, b|
irb(main):047* a[:count] <=> b[:count]
irb(main):048> end
(irb):47:in `block in <top (required)>': undefined method `[]' for nil (NoMethodError)
成功例2
ブロックパラメータの数(ブロックに渡す数)を1つにすると、sort_by
でも並び替えることができる。
irb(main):052* a.sort_by do |a|
irb(main):053* a[:count]
irb(main):054> end
=>
[{:name=>"player4", :count=>0},
{:name=>"player1", :count=>4},
{:name=>"player3", :count=>20},
{:name=>"player2", :count=>28}]
学んだこと
sort
メソッドはブロックパラメータに2つの要素を渡せるが、sort_by
メソッドは1つしか渡せない。