Rubyでarray.each_index.injectしたときの括弧は配列展開
こういうやつ
animals = { a1: { name: '犬', type: '哺乳類' }, a2: { name: '猫', type: '哺乳類' }, a3: { name: '蜥蜴', type: '爬虫類' } } mammals = animals.reduce([]) do |arr, (id, animal)| # <- ここの丸括弧 (animal[:type] == '哺乳類') ? (arr << animal) : arr end
実用例
「プレイヤーID」と「スコア」を持つハッシュがあるとして
player = { id: 1, score: 100 }
あるチームに所属する「プレイヤー毎のスコア」の合計値を独自に算出して「チームのスコア(≒チームの強さ)」を表したい。スコアの計算方法は、Clash of Clan のクランポイント計算と同様に、チーム内で1〜10位は各プレイヤーのスコアの50%、11〜30位は25%といった感じで係数が変わる。
これを Ruby で実装すると配列をイテレートしながら計算するために inject
を使うことになるが、プログラムを書く上で配列のインデックスが必要な場合は each_with_index
を挟むことになる。
# スコアが高い順にソート players.sort_by { |player| -player[:score] } # チーム内で上位にあるほどスコアを高く評価、51位以下は無視 players.each_with_index.inject(0) do |sum, (player, i)| sum += case i + 1 when 1..10 then (score * 0.50).round when 11..20 then (score * 0.25).round when 21..30 then (score * 0.12).round when 31..40 then (score * 0.10).round when 41..50 then (score * 0.03).round end end
このとき引数に sum, (player, i)
という謎の丸括弧がでてくるが、これは配列を意味する。
players.each_with_index.inject(0) do |sum, arr| sum, player = arr
このコードと同じ意味となり、引数内で展開してくれているだけ。