如何迭代添加键/值对,其中每个值都是一个数组?

时间:2013-10-18 20:27:31

标签: ruby hash

我正在迭代地将元素分配给散列,散列的值是由整数和数组组成的数组。我当前策略的一个玩具示例是这样的(递增数组的第一个元素,并将数字推送到数组的第二个元素):

aHash = Hash.new([0, []])

[1,3,5,1,1].each do |x|
  aHash[x] = [aHash[x][0] + 1, aHash[x][1] << x]
end

aHash # => {1=>[3, [1, 3, 5, 1, 1]], 3=>[1, [1, 3, 5, 1, 1]], 5=>[1, [1, 3, 5, 1, 1]]}

循环的递增部分似乎正在工作,但是不附加每个数组。所需的哈希应如下所示:

aHash # => {1=>[3, [1, 1, 1]], 3=>[1, [3]], 5=>[1, [5]]}

我也尝试过:

[1,3,5,1,1].each do |x|
  aHash[x] = [aHash.values_at(x)[0][0] + 1, aHash.values_at(x)[0][1] << x]
end

aHash # => {1=>[3, [1, 3, 5, 1, 1]], 3=>[1, [1, 3, 5, 1, 1]], 5=>[1, [1, 3, 5, 1, 1]]}

但是我得到了同样不正确的结果。

话虽如此,我的问题是:

  1. 如何正确初始化此哈希,假设这是我的问题,或者,如果不是......
  2. 正确递增哈希值的第一个元素,并附加哈希值的第二个元素?

2 个答案:

答案 0 :(得分:2)

aHash = Hash.new([0, []])

对象在Ruby中通过引用传递。您正在为默认值([0, []])创建一个数组,并在每次访问缺少的密钥时将引用传递给同一个数组

解决方案是在块中创建默认数组,以便使用每个丢失的键重新评估它:

aHash = Hash.new { [0, []] }

答案 1 :(得分:0)

如果我想要获得您正在寻找的结果,我会使用group_by函数。

a = [1,3,5,1,1]
p a.group_by{|x|x} #=> {5=>[5], 1=>[1, 1, 1], 3=>[3]}

如果你真的想要你想要的格式:

a = [1,3,5,1,1]
a_transformed = a.group_by{|x|x}.map{|x|[x.first,[x.last.size,x.last]]}
p Hash[a_transformed] #=> {1=>[3, [1, 1, 1]], 3=>[1, [3]], 5=>[1, [5]]}