解析嵌套JSON对象

bttbmeg0  于 2022-12-30  发布在  其他
关注(0)|答案(2)|浏览(192)

我需要递归地解析JSON对象。
下面是一个示例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: []
    }  
  ]
}

输出应该类似于:

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

基本上,constructed类型的对象应该有一个嵌套对象,primitive类型的对象应该直接有一个键-值对,对象可以很深,可以在同一层上有构造对象和原始对象(如我的例子)。
下面是我目前的代码:

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])    
  }
}

这是我的小提琴:https://jsfiddle.net/kzaiwo/0v6a2tp8/16/
但是我不能让它遍历整个对象。递归不是我真正擅长的领域,但我认为这是实现它的最佳方式。我错过了什么?请帮助!
谢谢!

mutmk8jj

mutmk8jj1#

希望这对你有帮助,

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);
uklbhaso

uklbhaso2#

您可以使用以下递归reduceObj(obj)函数,该函数简短而简洁:

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);

ES6之前的函数语法:

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

相关问题