Help us understand the problem. What is going on with this article?

Rubyで二次元配列をsortしたい

More than 5 years have passed since last update.

例えば以下の様な ["名前", コメント数] という構造を持つ配列があって、その内側の配列の二番目の要素(この例では「コメント数」)でソートしたい。

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away