扁平化嵌套哈希数组

时间:2019-01-16 02:56:15

标签: ruby-on-rails arrays hash nested

我有一个嵌套的哈希数组,看起来像这样:

[{"month"=>1,
  "percentiles"=>{"25"=>768.06, "50"=>1868.5, "75"=>3043.79, "90"=>4161.6},
  "total_revenue"=>1308620.0,
  "year"=>2017},
 {"month"=>2,
  "percentiles"=>{"25"=>922.63, "50"=>2074.31, "75"=>3048.87, "90"=>4018.6},
  "total_revenue"=>1105860.0,
  "year"=>2017}]

我想介绍一下:

[{"month"=>1,
      "25"=>768.06, "50"=>1868.5, "75"=>3043.79, "90"=>4161.6,
      "total_revenue"=>1308620.0,
      "year"=>2017},
     {"month"=>2,
      "25"=>922.63, "50"=>2074.31, "75"=>3048.87, "90"=>4018.6,
      "total_revenue"=>1105860.0,
      "year"=>2017}]

我一直在寻找并测试不同的方法,但是没有运气。关于如何做到这一点的任何想法?最终目标是将这些文件批量更新/插入数据库,因此,如果有更好的方法可以实现这一点,我希望看到另一种方法。

1 个答案:

答案 0 :(得分:0)

如果您不介意就地修改数组,则可以说:

array.each { |h| h.merge!(h.delete('percentiles')) }

如果您不确定所有哈希都具有'percentiles'键,那么您可以说:

# Explicitly check
array.each { |h| h.merge!(h.delete('percentiles')) if(h.has_key?('percentiles')) }
# Convert possible `nil`s to `{ }`
array.each { |h| h.merge!(h.delete('percentiles').to_h) }
# Filter before merging
array.select { |h| h.has_key?('percentiles') }.each { |h| h.merge!(h.delete('percentiles')) }

如果要展平所有哈希值,则可以执行以下操作:

array.each do |h|
  h.keys.each do |k|
    if(h[k].is_a?(Hash))
      h.merge!(h.delete(k))
    end
  end
end

如果您不想修改数组中的哈希,请使用以下变量:

flat = array.map(&:dup).each { |h| h.merge!(h.delete('percentiles')) }

flat = array.map do |e|
  e.each_with_object({}) do |(k, v), h|
    if(v.is_a?(Hash))
      h.merge!(v)
    else
      h[k] = v
    end
  end
end