以动态深度访问嵌套数组

时间:2017-07-19 20:26:54

标签: javascript json

我有以下json,它遵循一个特定的模式,但每个对象可以有任意数量的children,每个children个对象可以有任意数量的children 1}} ..

[
  {
    "name": "1st level",
    "parentId": "",
    "id": "dummyvalue1",
    "children": [
      {
        "name": "2nd level child",
        "parentId": "dummyvalue1",
        "id": "dummyvalue2"
      },
      {
        "name": "another 2nd level child",
        "id": "dummyvalue3",
        "children": [
          {
            "name": "3rd level child",
            "id": "dummyvalue4",
            "children": [
              {
                "name": "4th level child",
                "parentId": "dummyvalue4",
                "id": "dummyvalue5"
              }
            ],
            "parentId": "dummyvalue3"
          }
        ],
        "parentId": "dummyvalue1"
      }
    ]
  }
]

问题是,我只需要在这个嵌套的object / array结构中访问特定深度的对象。

depth是动态的。

如果depth等于3,那么我想在该级别的children数组中添加一个新的虚拟对象。所以新结构看起来像这样..

[
  {
    "name": "1st level",
    "parentId": "",
    "id": "dummyvalue1",
    "children": [
      {
        "name": "2nd level child",
        "parentId": "dummyvalue1",
        "id": "dummyvalue2"
      },
      {
        "name": "another 2nd level child",
        "id": "dummyvalue3",
        "children": [
          {
            "name": "3rd level child",
            "id": "dummyvalue4",
            "children": [
              {
                "name": "4th level child",
                "parentId": "dummyvalue4",
                "id": "dummyvalue5"
              }
            ],
            "parentId": "dummyvalue3"
          },
          {
            "name": "NEW OBJECT",
            "parentId": "dummyvalue3",
            "id": "random"
          }
        ],
        "parentId": "dummyvalue1"
      }
    ]
  }
]

有干净的方法吗?而不是巨大的循环试图迭代到正确的水平。也不认为我可以使用点表示法,因为级别数和depth变量是动态的

1 个答案:

答案 0 :(得分:1)

我已经创建了这个功能:

function addChild(currentChild, childToAdd, depth) {
  if (depth === 1) {
    currentChild.children.push(childToAdd);
    return;
  }

  const nextChild = currentChild.children.filter(child => child.children && child.children.length)[0];

  if (!nextChild) {
     if (currentChild.children && currentChild.children.length) {
       currentChild.children[0].children = [childToAdd];
     } else {
       currentChild.children = [childToAdd];
     }
     return;
  }

  addChild(nextChild, childToAdd, depth - 1);
}

需要3个参数:

  1. 现在的孩子
  2. 要添加的孩子
  3. 贯穿其余深度
  4. 如果depth为1,则只需将child添加到children。如果没有,它会查看children内部,使用children获取第一个并对同一函数进行递归调用。

    const data = [
      {
        "name": "1st level",
        "parentId": "",
        "id": "dummyvalue1",
        "children": [
          {
            "name": "2nd level child",
            "parentId": "dummyvalue1",
            "id": "dummyvalue2"
          },
          {
            "name": "another 2nd level child",
            "id": "dummyvalue3",
            "children": [
              {
                "name": "3rd level child",
                "id": "dummyvalue4",
                "children": [
                  {
                    "name": "4th level child",
                    "parentId": "dummyvalue4",
                    "id": "dummyvalue5"
                  }
                ],
                "parentId": "dummyvalue3"
              }
            ],
            "parentId": "dummyvalue1"
          }
        ]
      }
    ]
    
    function addChild(currentChild, childToAdd, depth) {
      if (depth === 1) {
        currentChild.children.push(childToAdd);
        return;
      }
      
      const nextChild = currentChild.children.filter(child => child.children && child.children.length)[0];
      
      if (!nextChild) {
         if (currentChild.children && currentChild.children.length) {
           currentChild.children[0].children = [childToAdd];
         } else {
           currentChild.children = [childToAdd];
         }
         return;
      }
    
      addChild(nextChild, childToAdd, depth - 1);
    }
    
    addChild(data[0], {foo: 'bar'}, 3);
    addChild(data[0], {bar: 'baz'}, 2);
    addChild(data[0], {baz: 'foo'}, 1);
    addChild(data[0], {extraChild: 'foo'}, 4);
    
    
    console.log(data);