从数组中提取值

时间:2015-04-03 14:53:23

标签: ruby arrays

从下面的哈希值中,需要提取每个参数的值:

array_of_hashes = [{type: "test1", value: 1}, {type: "test1", value: 1}, {type: "test2", value: 1}, {type: "test2", value: 1}]

我想得到这样的东西:

array_of_hashes = [{"test1" => [{type: "test1", value: 1}, {type: "test1", value: 1}}], {"test2" => {type: "test2", value: 1}, {type: "test2", value: 1}}]

转换此数组的最有效方法是什么?这个数组可能有2 000 000个值。

2 个答案:

答案 0 :(得分:2)

您可以使用group_by

array_of_hashes.group_by { |h| h[:type] }
# => {"test1"=>[{:type=>"test1", :value=>1}, {:type=>"test1", :value=>1}], "test2"=>[{:type=>"test2", :value=>1}, {:type=>"test2", :value=>1}]} 

答案 1 :(得分:0)

如果在示例中哈希按:type的值排序,您可能会发现Enumerable#chunk(然后转换为哈希)比group_by更快:< / p>

Hash[array_of_hashes.chunk { |h| h[:type] }.to_a]

我建议你比较一下。 编辑:我测试过。如下所示,group_by似乎更快。

def mk_arr(n,m)
  n.times.with_object([]) { |i,a| m.times { a << { type: "test#{i}", value: 1 } } }
end

mk_arr(3,2)
  #=> [{:type=>"test0", :value=>1}, {:type=>"test0", :value=>1},
  #    {:type=>"test1", :value=>1}, {:type=>"test1", :value=>1},
  #    {:type=>"test2", :value=>1}, {:type=>"test2", :value=>1}] 

require 'benchmark'  
def bench_em(n,m)
  arr = mk_arr(n,m)
  puts "n = #{n}, m = #{m}"
  print "group_by: "
  puts Benchmark.measure { arr.group_by { |h| h[:type] } }     
  print "chunk   : "
  puts Benchmark.measure { Hash[arr.chunk { |h| h[:type] }.to_a] }
  puts
end

              user     system      total        real
n = 100000, m = 2
group_by:   0.090000   0.000000   0.090000 (  0.095301)
chunk   :   0.160000   0.000000   0.160000 (  0.166608)

n = 100000, m = 4
group_by:   0.250000   0.010000   0.260000 (  0.252951)
chunk   :   0.260000   0.000000   0.260000 (  0.261747)

n = 100000, m = 8
group_by:   0.370000   0.010000   0.380000 (  0.386423)
chunk   :   0.450000   0.000000   0.450000 (  0.447134)

n = 1000000, m = 4
group_by:   2.740000   0.040000   2.780000 (  2.775030)
chunk   :   3.690000   0.070000   3.760000 (  3.790305)