例えば以下の様な ["名前", コメント数]
という構造を持つ配列があって、その内側の配列の二番目の要素(この例では「コメント数」)でソートしたい。
nogizaka = [
["秋元真夏", 4165],
["生田絵梨花", 3400],
["生駒里奈", 3305],
["伊藤万理華", 2746],
["北野日奈子", 0],
["佐々木琴子", 310],
["白石麻衣", 2235],
["寺田蘭世", 1860],
["中田花奈", 3859],
["中元日芽香", 4580],
["西野七瀬", 2409],
["橋本奈々未", 3581],
["深川麻衣", 5823],
["星野みなみ", 339],
["堀未央奈", 3035],
]
ここでは降順の結果が得られるようなやり方を幾つか紹介
(1) sort (ブロックの中のaとbを逆にすることで降順になる)
nogizaka.sort { |a, b| b[1] <=> a[1] }
(2) sort reverse
nogizaka.sort { |a, b| a[1] <=> b[1] }.reverse
(3) sort_by reverse その1
nogizaka.sort_by { |_, b| b }.reverse
(4) sort_by reverse その2
nogizaka.sort_by(&:last).reverse
いずれも同じ結果が得られる。(コメント数で降順にソート)
[
["深川麻衣", 5823],
["中元日芽香", 4580],
["秋元真夏", 4165],
["中田花奈", 3859],
["橋本奈々未", 3581],
["生田絵梨花", 3400],
["生駒里奈", 3305],
["堀未央奈", 3035],
["伊藤万理華", 2746],
["西野七瀬", 2409],
["白石麻衣", 2235],
["寺田蘭世", 1860],
["星野みなみ", 339],
["佐々木琴子", 310],
["北野日奈子", 0]
]
ちなみに...
どれを使えばよいのかBenchmarkをとってみる
require 'benchmark'
ary = []
1000.times {
ary << ['hoge', rand(100)]
}
n = 1000
Benchmark.bm(25) do |x|
x.report('sort') { n.times { ary.sort { |a, b| b[1] <=> a[1] }}}
x.report('sort reverse') { n.times { ary.sort { |a, b| a[1] <=> b[1] }.reverse }}
x.report('sort_by{|_,b|b} reverse') { n.times { ary.sort_by { |a, b| b }.reverse }}
x.report('sort_by(&:last) reverse') { n.times { ary.sort_by(&:last).reverse }}
end
#=>
# user system total real
# sort 0.800000 0.000000 0.800000 ( 0.811129)
# sort reverse 0.800000 0.010000 0.810000 ( 0.802099)
# sort_by{|_,b|b} reverse 0.450000 0.000000 0.450000 ( 0.456646)
# sort_by(&:last) reverse 0.450000 0.010000 0.460000 ( 0.454975)
結果
とりあえず sort
より sort_by
を使ったほうが良さそう。
sort_by ならどちらのやり方でも大差ないと思う。
参考
http://stackoverflow.com/questions/7033719/sorting-a-two-dimensional-array-by-second-value