64
45

More than 5 years have passed since last update.

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

Posted at

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

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

64
45
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
64
45