Ruby - 将数组合并为哈希

时间:2015-07-23 19:14:46

标签: ruby

我有一个看起来像这样的数组:

array = [[:foo, :bar], [:foo, :baz], [:baz, {a: 1, b: 2}], [:baz, {c: 1, d:2}]]

我需要把它变成一个看起来像这样的哈希:

{:foo =>[:bar, :baz], :baz => {a: 1, b: 2, c: 1, d: 2}}

这是我到目前为止的代码:

def flatten(array)
  h = {}
  array.each_with_object({}) do |(k, v), memo|
    if v.is_a?(Hash)
      memo[k] = h.merge!(v)
    else
      # What goes here?
    end
  end
end

如果这样使用:

flatten(array)

输出:

{baz => {:a => 1, :b => 2, :c => 1, :d => 2}}

有人可以指点我正确的方向吗?帮助赞赏。

3 个答案:

答案 0 :(得分:1)

def convert(arr)
  arr.each_with_object({}) do |a,h|
    h[a.first] =        
      case a.last
      when Hash
        (h[a.first] || {}).update(a.last)
      else
        (h[a.first] || []) << a.last
      end
  end
end

convert array
  #=> {:foo=>[:bar, :baz], :baz=>{:a=>1, :b=>2, :c=>1, :d=>2}}

答案 1 :(得分:0)

Hash[ array.group_by(&:first).map{ |k,a| [k,a.map(&:last)] } ]

答案 2 :(得分:0)

这是我尝试解决这个问题。我必须假设在输入数组中,类似于:baz的条目将始终与Hash个对象配对。如果您有一个:baz带有符号而另一个带有散列,则该解决方案将无效。

array = [[:foo, :bar], [:foo, :baz], [:baz, {a: 1, b: 2}], [:baz, {c: 1, d:2}]]

h = Hash.new
array.each do |n1, n2|
    if n2.class == Hash
      h[n1] = (h[n1] || {}).merge(n2) 
    else
      h[n1] = (h[n1] || []) << n2
    end
end
p h

<强>输出

{:foo=>[:bar, :baz], :baz=>{:a=>1, :b=>2, :c=>1, :d=>2}}
[Finished in 0.1s]