3

ハッシュの配列の配列があります。

items = 
[{ "item_9": 152 }, { "item_2": 139 }, { "item_13": 138 }, { "item_72": 137 }, { "item_125": 140 }, { "item_10": 144 }]
[{ "item_9": 152 }, { "item_2": 139 }, { "item_13": 138 }, { "item_72": 137 }, { "item_125": 140 }, { "item_10": 146 }]
[{ "item_9": 152 }, { "item_2": 139 }, { "item_13": 138 }, { "item_72": 137 }, { "item_125": 140 }, { "item_10": 147 }]
[{ "item_9": 152 }, { "item_2": 139 }, { "item_13": 138 }, { "item_72": 137 }, { "item_125": 140 }, { "item_10": 148 }]
[{ "item_9": 152 }, { "item_2": 139 }, { "item_13": 138 }, { "item_72": 137 }, { "item_125": 140 }, { "item_10": 153 }]
.
.
.
[{ "item_9": 152 }, { "item_2": 145 }, { "item_13": 150 }, { "item_72": 154 }, { "item_125": 141 }, { "item_10": 144 }]
[{ "item_9": 152 }, { "item_2": 145 }, { "item_13": 150 }, { "item_72": 154 }, { "item_125": 141 }, { "item_10": 146 }]
[{ "item_9": 152 }, { "item_2": 145 }, { "item_13": 150 }, { "item_72": 154 }, { "item_125": 141 }, { "item_10": 147 }]
[{ "item_9": 152 }, { "item_2": 145 }, { "item_13": 150 }, { "item_72": 154 }, { "item_125": 141 }, { "item_10": 148 }]
[{ "item_9": 152 }, { "item_2": 145 }, { "item_13": 150 }, { "item_72": 154 }, { "item_125": 141 }, { "item_10": 153 }]

私がやりたいのは、それをハッシュの配列に変更することです...

items =
{"item_9"=>152, "item_2"=>145, "item_13"=>150, "item_72"=>154, "item_125"=>141, "item_10"=>146}
{"item_9"=>152, "item_2"=>145, "item_13"=>150, "item_72"=>154, "item_125"=>141, "item_10"=>147}
{"item_9"=>152, "item_2"=>145, "item_13"=>150, "item_72"=>154, "item_125"=>141, "item_10"=>148}
{"item_9"=>152, "item_2"=>145, "item_13"=>150, "item_72"=>154, "item_125"=>141, "item_10"=>153}

私はこれを使用してこれを行うことができると信じています...

items.map! { |item| item.reduce({}, :merge) }

ただし、あまり高性能ではありません。少なくとも、1 億 4000 万件のレコードがある場合、十分なパフォーマンスが得られません。これを行うより良い方法はありますか?

4

3 に答える 3

3

おそらく少し長くなりますが、はるかに高速に動作します。

require 'benchmark'

items = [
  [{ item_9: 152 }, { item_2: 139 }, { item_13: 138 }, { item_72: 137 }, { item_125: 140 }, { item_10: 146 }],
  [{ item_9: 152 }, { item_2: 139 }, { item_13: 138 }, { item_72: 137 }, { item_125: 140 }, { item_10: 147 }],
  [{ item_9: 152 }, { item_2: 139 }, { item_13: 138 }, { item_72: 137 }, { item_125: 140 }, { item_10: 148 }],
  [{ item_9: 152 }, { item_2: 139 }, { item_13: 138 }, { item_72: 137 }, { item_125: 140 }, { item_10: 153 }],
  [{ item_9: 152 }, { item_2: 145 }, { item_13: 150 }, { item_72: 154 }, { item_125: 141 }, { item_10: 144 }],
  [{ item_9: 152 }, { item_2: 145 }, { item_13: 150 }, { item_72: 154 }, { item_125: 141 }, { item_10: 146 }],
  [{ item_9: 152 }, { item_2: 145 }, { item_13: 150 }, { item_72: 154 }, { item_125: 141 }, { item_10: 147 }],
]

n = 100_000
Benchmark.bm do |b|
  b.report do
    n.times do |i|
      items.map { |item| item.reduce({}, :merge) }
    end
  end
  b.report do
    n.times do |i|
      # the winer
      items.map { |item| item.reduce({}, :update) }
    end
  end
  b.report do
    n.times do |i|
      items.map { |i| i.inject({}) { |f,c| f.update c } }
    end
  end
end

@toklandが示唆しているように、item.reduce({}, :update)さらに高速です。

   user     system      total        real
6.300000   0.080000   6.380000 (  6.386180)
1.840000   0.020000   1.860000 (  1.860073)
2.220000   0.020000   2.240000 (  2.237294)

ありがとう@tokland

于 2012-11-08T20:38:25.967 に答える
0

2 レベルの配列 (ペア内に他の配列がない) があり、各ペアに正確に 2 つの項目があることが確実な場合は、これを使用する方が高速で短いです。

array = [['A', 'a'], ['B', 'b'], ['C', 'c']]
hash = Hash[*array.flatten]

2 レベル以上の深さの配列の場合、これは間違った結果またはエラー (一部の入力の場合) を返します。

array = [['A', 'a'], ['B', 'b'], ['C', ['a', 'b', 'c']]]
hash = Hash[*array.flatten]
# => {"A"=>"a", "B"=>"b", "C"=>"a", "b"=>"c"}

ただし、Ruby 1.8.7 以降を実行している場合は、引数を Array#flatten に渡して、1 レベルだけフラット化することができます。

# on Ruby 1.8.7+
hash = Hash[*array.flatten(1)]
# => {"A"=>"a", "B"=>"b", "C"=>["a", "b", "c"]}
于 2015-09-30T03:50:51.160 に答える
0

パフォーマンスが問題になるため、データに関する興味深い事実に気付くだけでなく、 forloopsの時間になるかもしれません。yieldたとえば、データに多くの反復項目があるようです。それはルールですか、それともただの偶然ですか?

于 2012-11-08T20:29:53.143 に答える