Home > database >  Parsing a Nested JSON Object
Parsing a Nested JSON Object

Time:12-30

I need to parse a JSON object recursively.

Here is a sample JSON:

const obj = {
  tag: 'AA',
  type: 'constructed',
  value: 'ABCD1',
  child: [
    {
      tag: 'BB',
      type: 'constructed',
      value: 'ABCD2',      
      child: [
        {
          tag: 'CC',
          type: 'constructed',
          value: 'ABCD3',          
          child: [
            {
              tag: 'DD',
              type: 'primitive',
              value: 'ABCD4',
              child: []
            },
            {
              tag: 'EE',
              type: 'constructed',
              value: 'ABCD5',
              child: [
                {
                  tag: 'FF',
                  type: 'primitive',
                  value: 'ABCD6',
                  child: []
                },
                {
                  tag: 'GG',
                  type: 'primitive',
                  value: 'ABCD7',
                  child: []
                }                
              ]
            },
            {
              tag: 'HH',
              type: 'primitive',
              value: 'ABCD8',
              child: []
            }  
          ]
        }
      ]
    },
    {
      tag: 'II',
      type: 'primitive',
      value: 'ABCD9',
      child: []
    }  
  ]
}

And the output should be something like:

{
  "AA": [
    {
      "BB": [
        {
          "CC": [
            {
              "DD": "ABCD4"
            },
            {
              "EE": [
                {
                  "FF": "ABCD6"
                },
                {
                  "GG": "ABCD7"
                }
              ]
            },
            {
              "HH": "ABCD8"
            }
          ]
        }
      ]
    },
    {
      "II": "ABCD9"
    }
  ]
}

Basically, those with type constructed should have a nested object and those that are primitive should directly have a key-value pair. The object could go very deep, and can have both constructed and primitive objects on the same level (as on my example).

Here is my current code:

let jsonOutput = {}
parseData(obj, jsonOutput)

function parseData(jsonToParse, jsonOutput) {
  const type = jsonToParse.type
  const tag = jsonToParse.tag
  const value = jsonToParse.value
  let prev = jsonOutput
  
  if (type === 'constructed') {
    prev[tag] = []
    return parseData(jsonToParse.child[0], prev[tag])
  } else if (type === 'primitive') {
    prev[tag] = value
    return parseData(jsonToParse.child, prev[tag])    
  }
}

Here is my fiddle: https://jsfiddle.net/kzaiwo/0v6a2tp8/16/

But I can't make it iterate through the whole object. Recursions are not really my strongest area, but I think this is the most optimal way to implement it.. What am I missing? Help please!

Thanks!

CodePudding user response:

Hope this may help you,

const obj = { tag: 'AA', type: 'constructed', value: 'ABCD1', child: [ { tag: 'BB', type: 'constructed', value: 'ABCD2', child: [ { tag: 'CC', type: 'constructed', value: 'ABCD3', child: [ { tag: 'DD', type: 'primitive', value: 'ABCD4', child: [] }, { tag: 'EE', type: 'constructed', value: 'ABCD5', child: [ { tag: 'FF', type: 'primitive', value: 'ABCD6', child: [] }, { tag: 'GG', type: 'primitive', value: 'ABCD7', child: [] } ] }, { tag: 'HH', type: 'primitive', value: 'ABCD8', child: [] } ] } ] }, { tag: 'II', type: 'primitive', value: 'ABCD9', child: [] } ] }

function parseData(obj) {

const result = {};

if (obj.type === 'primitive') {
    result[obj.tag] = obj.value;
} else if (obj.type === 'constructed') {
    result[obj.tag] = obj.child.map(parseData);
}

return result;
}

const parsedJson = parseData(obj);
console.log(parsedJson);

CodePudding user response:

You can use the following recursive reduceObj(obj) function, short and sweet:

const obj = { tag: 'AA', type: 'constructed', value: 'ABCD1', child: [ { tag: 'BB', type: 'constructed', value: 'ABCD2', child: [ { tag: 'CC', type: 'constructed', value: 'ABCD3', child: [ { tag: 'DD', type: 'primitive', value: 'ABCD4', child: [] }, { tag: 'EE', type: 'constructed', value: 'ABCD5', child: [ { tag: 'FF', type: 'primitive', value: 'ABCD6', child: [] }, { tag: 'GG', type: 'primitive', value: 'ABCD7', child: [] } ] }, { tag: 'HH', type: 'primitive', value: 'ABCD8', child: [] } ] } ] }, { tag: 'II', type: 'primitive', value: 'ABCD9', child: [] } ] }

function reduceObj(obj) {
  return { [obj.tag]: obj.type === 'primitive'
    ? obj.value
    : obj.child.map(reduceObj) };
}

const result = reduceObj(obj);
console.log(result);

Function syntax prior to ES6:

    function reduceObj(obj) {
      let o = {};
      o[obj.tag] = obj.child.map(function(childObj) {
        return obj.type === 'primitive'
          ? obj.value
          : reduceObj(childObj);
      });
      return o;
    }
  • Related