Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten a nested json object

I'm looking for a method that will flatten a "json" hash into a flattened hash but keep the path information in the flattened keys. For example:

h = {"a" => "foo", "b" => [{"c" => "bar", "d" => ["baz"]}]}

flatten(h) should return:

{"a" => "foo", "b_0_c" => "bar", "b_0_d_0" => "baz"}
like image 256
pguardiario Avatar asked May 23 '12 02:05

pguardiario


People also ask

How do I flatten a nested JSON object?

Flatten a JSON object: var flatten = (function (isArray, wrapped) { return function (table) { return reduce("", {}, table); }; function reduce(path, accumulator, table) { if (isArray(table)) { var length = table.

How do I flatten JSON?

Approach to flatten JSON: There are many ways to flatten JSON. There is one recursive way and another by using the json-flatten library. Now we can flatten the dictionary array by a recursive approach which is quite easy to understand. The recursive approach is a bit slower than using the json-flatten library.

What does it mean to flatten a JSON?

Use the Flatten JSON Objects extension to convert a nested data layer object into a new object with only one layer of key/value pairs. For more advanced options in converting a data layer, see the Data Layer Converter.


1 Answers

This should solve your problem:

h = {'a' => 'foo', 'b' => [{'c' => 'bar', 'd' => ['baz']}]}

module Enumerable
  def flatten_with_path(parent_prefix = nil)
    res = {}

    self.each_with_index do |elem, i|
      if elem.is_a?(Array)
        k, v = elem
      else
        k, v = i, elem
      end

      key = parent_prefix ? "#{parent_prefix}.#{k}" : k # assign key name for result hash

      if v.is_a? Enumerable
        res.merge!(v.flatten_with_path(key)) # recursive call to flatten child elements
      else
        res[key] = v
      end
    end

    res
  end
end

puts h.flatten_with_path.inspect
like image 142
Hck Avatar answered Nov 15 '22 05:11

Hck