在ruby中创建嵌套哈希或使用group_by

时间:2015-03-11 19:29:52

标签: ruby arrays hash

我有一个数组如下:

my_array = [
  [1426049999000, "Apple", 2.7235],
  [1426049999000, "Orange", 2.942],
  [1424235599000, "Apple", 1.124],
  [1424235599000, "Orange", 1.115]
]

我想要哈希哈希:

{
  :"Apple" => {1426049999000 => 2.7235, 1424235599000 => 1.124},
  :"Orange" => {1426049999000 => 2.942, 1424235599000 => 1.115}
}

或数组哈希:

{
  :"Apple" => [[1426049999000, 2.7235], [1424235599000, 1.124]],
  :"Orange" => [[1426049999000, 2.942], [1424235599000, 1.115]]
}

如何创建嵌套哈希或我想要的数组哈希?

我试过了:

my_array.group_by { |s| s[1] }

收到的输出:

{
  :"Apple" => [[1426049999000, "Apple", 2.7235], [1424235599000, "Apple", 1.124]],
  :"Orange" => [[1426049999000, "Orange", 2.942], [1424235599000, "Orange", 1.115]]
}

4 个答案:

答案 0 :(得分:2)

我做:

my_array = [[1426049999000, "Apple", 2.7235], [1426049999000, "Orange", 2.942], [1424235599000, "Apple", 1.124], [1424235599000, "Orange", 1.115]]
my_array.each_with_object({}) { |a, h| (h[a[1]] ||= []) << a.values_at(0, 2) }
# => {"Apple"=>[[1426049999000, 2.7235], [1424235599000, 1.124]], "Orange"=>[[1426049999000, 2.942], [1424235599000, 1.115]]}
my_array.each_with_object({}) { |a, h| (h[a[1]] ||= {}).update(a[0] => a[2]) }
# => {"Apple"=>{1426049999000=>2.7235, 1424235599000=>1.124}, "Orange"=>{1426049999000=>2.942, 1424235599000=>1.115}}

答案 1 :(得分:1)

我的朋友@Arup已经指出我的后者(原始)表达式没有返回OP请求的结果。这是事实,但是更准确地说,因为我提供了两种返回相同结果的方法(一个哈希值为散列数组的哈希),两个表达式都没有返回请求的结果。

无论如何,我修改了原来的答案,以符合OP的指示,并希望感谢Arup的鹰眼。

my_array = [[1426, "Apple",  2.723],
            [1426, "Orange", 2.942],
            [1424, "Apple",  1.124],
            [1424, "Orange", 1.115]]

表达式#1

生成具有哈希值的散列:

my_array.each_with_object({}) { |(v1,fruit,v2),h|
  h.update(fruit.to_sym => {v1=>v2}) { |_,ov,nv| ov.update(nv) } }
  #=> {:Apple=>{1426=>2.723,  1424=>1.124},
  #    :Orange=>{1426=>2.942, 1424=>1.115}}

或者是数组数组的值:

my_array.each_with_object({}) { |(v1,fruit,v2),h|
  h.update(fruit.to_sym => [[v1, v2]]) { |_,ov,nv| ov+nv } }
  #=> {:Apple=> [[1426, 2.723], [1424, 1.124]],
   #   :Orange=>[[1426, 2.942], [1424, 1.115]]} 

我会建议后者,如果[1424, "Apple", 1.124]中的my_array代替[1426, "Apple", 1.124],则1426不会出现问题键。

表达式#2

my_array.each_with_object(Hash.new {|h,k| h[k]=[]}) { |(v1,fruit,v2),h|
  h[fruit.to_sym] << [v1,v2] }
  #=> {:Apple=> [[1426, 2.723], [1424, 1.124]],
  #    :Orange=>[[1426, 2.942], [1424, 1.115]]} 

答案 2 :(得分:0)

groups =  { :"Apple" => [[1426049999000, "Apple", 2.7235], [1424235599000, "Apple", 1.124]],
      :"Orange" => [[1426049999000, "Orange", 2.942], [1424235599000, "Orange", 1.115]]}

groups.each{|k,v| v.each{|ar| ar.delete(k.to_s)}}
p groups # => {:Apple=>[[1426049999000, 2.7235], [1424235599000, 1.124]], :Orange=>[[1426049999000, 2.942], [1424235599000, 1.115]]}

答案 3 :(得分:0)

p my_array.group_by{|x| x.delete_at(1)} #=> {"Apple"=>[[1426049999000, 2.7235], [1424235599000, 1.124]], "Orange"=>[[1426049999000, 2.942], [1424235599000, 1.115]]}


# or my_array.map(&:rotate).group_by(&:shift)