展平哈希并连接密钥

时间:2015-12-14 15:39:26

标签: ruby hash flatten

我有这样的哈希:

{
 "category" => ["sport", "gaming", "other"],
 "duration" => 312,
 "locations" => { 
    "688CQQ" => {"country" => "France", "state" => "Rhône-Alpes"},
    "aUZCAQ" => {"country" => "France", "state" => "Île de France"}
  }
}

如果值是哈希值,我想通过展平值将其缩小为哈希而不进行嵌套。在最终值中,我应该只有这样的整数,字符串或数组:

{
  "category" => ["sport", "gaming", "other"],
  "duration" => 312,
  "locations_688CQQ_country" => "France",
  "locations_688CQQ_state" => "Rhône-Alpes",
  "locations_aUZCAQ_country" => "France",
  "locations_aUZCAQ_state" => "Île de France"
}

我想要一个适用于任何嵌套级别的函数。我怎么能用红宝石做到这一点?

3 个答案:

答案 0 :(得分:2)

这是一种递归方法,其中h是您的哈希值。

def flat_hash(h)
  h.reduce({}) do |a, (k,v)|
    tmp = v.is_a?(Hash) ? flat_hash(v).map { |k2,v2| ["#{k}_#{k2}",v2]}.to_h : { k => v }
    a.merge(tmp)
  end
end

答案 1 :(得分:1)

改编自https://stackoverflow.com/a/9648515/311744

def flat_hash(h, f=nil, g={})
  return g.update({ f => h }) unless h.is_a? Hash
  h.each { |k, r| flat_hash(r, [f,k].compact.join('_'), g) }
  g
end

答案 2 :(得分:0)

改编自https://stackoverflow.com/a/34271380/2066657

请在堆放我的时候在这里。

class ::Hash
  def flat_hash(j='_', h=self, f=nil, g={})
    return g.update({ f => h }) unless h.is_a? Hash
    h.each { |k, r| flat_hash(j, r, [f,k].compact.join(j), g) }
    g
  end
end

现在我们可以做

irb> {'foo' =>{'bar'=>{'squee'=>'woot'}}}.flat_hash('')
=> {"foobarsquee"=>"woot"}

您欠互联网甲骨文一个'!'方法。