LoginSignup
25
18

More than 3 years have passed since last update.

ハッシュから特定のキーのハッシュを作る

Last updated at Posted at 2015-02-13

テストを書いてる時にふと気になったので検証してみた.

結果から言うと

Ruby2.5以降とRailsではコレが鉄板
早くてシンプル!

months.slice(:jan, :jun, :jul)
# => {:jan=>"1月", :jun=>"6月", :jul=>"7月"}

Ruby 2.4以前でRailsを使わない場合は

シンプルに書くなら

months.select {|k,_| [:jan, :jun, :jul].include?(k) }
# => {:jan=>"1月", :jun=>"6月", :jul=>"7月"}

早いけど、少し長い

keys = [:jan, :jun, :jul]
keys.each_with_object({}){|k, hash| hash[k] = months[k] if months.key?(k) }
# => {:jan=>"1月", :jun=>"6月", :jul=>"7月"}

検証

思いつく限りと、コメントで頂いた方法で検証してみた.

リテラルで表記してるから、インタプリタがうまいことやってて同じくらいの結果を期待してたけど、結構違うもんだな。

benchmark
ruby 2.2.0
                                     user     system      total        real
Enumerable#each_with_object      1.010000   0.000000   1.010000 (  1.020658)
Hash#select: out of loop         2.010000   0.000000   2.010000 (  2.027411)
Hash#select: in the loop         2.560000   0.010000   2.570000 (  2.583571)
Hash#slice: active_support       1.570000   0.010000   1.580000 (  1.590525)
require 'benchmark'
require 'active_support'

puts "ruby #{RUBY_VERSION}"
n = 1000000
months = {
  jan: "1月", feb: "2月", mar: "3月", apr: "4月", may: "5月", jun: "6月",
  jul: "7月", aug: "8月", sep: "9月", oct: "10月", nov: "11月", dec: "12月"
}
Benchmark.bm(30) do |x|
  x.report("Enumerable#each_with_object") do
    keys = [:jan, :jun, :jul]
    n.times do
      keys.each_with_object({}){|k, hash| hash[k] = months[k] if months.key?(k) }
    end
  end
  x.report("Hash#select: out of loop") do
    keys = [:jan, :jun, :jul]
    n.times do
      months.select {|k,_| keys.include?(k) }
    end
  end
  x.report("Hash#select: in the loop") do
    n.times do
      months.select {|k,_| [:jan, :jun, :jul].include?(k) }
    end
  end
  x.report("Hash#slice: active_support") do
    n.times do
      months.slice(:jan, :jun, :jul)
    end
  end
end
25
18
7

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
25
18