繁体   English   中英

递归搜索数组中的嵌套对象并更新其子对象

[英]Recursively search for a nested object in array and update its children

我正在尝试通过对象的唯一 id递归搜索对象的数组,然后将对象推入其部分数组,然后返回整个数组

例如,这是我要搜索的数组:

car =    [
    {
        id: 13,
        title: 'Component13',
        parts: [
           {
               id: 784,
               title: 'Component242',
               parts: [

               ]
           },
           {
               id: 9,
               type: 'mitigation',
               parts: [
                      {
                          id: 68,
                          type: 'mitigation22',
                          parts: [

                          ]
                      },
                      {
                          id: 88,
                          type: 'threat',
                          parts: [

                          ]
                      }
                ]
           }
      ]
},
{
    id: 3,
    title: 'Component13',
    parts: [
           {
               id: 60,
               title: 'Component34',
               parts: [

               ]
           },
           {
               id: 51,
               type: 'threat',
               parts: [
                      {
                           id: 38,
                           type: 'mitigation22',
                           parts: [

                           ]
                     }
               ]
          }
      ]
   }
]

如果我想将此对象插入到 id 38 中的部分子数组中:

{
    id: 34,
    title: 'Component211',
    parts: [

    ]
}

......结果应该是这样的:

  ...commented out the first block to save space
 {
    id: 3,
    title: 'Component13',
    parts: [
          {
              id: 60,
              title: 'Component34',
              parts: [

              ]
          },
          {
              id: 51,
              type: 'threat',
              parts:[
                   {
                        id: 38,
                        type: 'mitigation22',
                        parts: [
                             {
                                 id: 34,
                                 title: 'Component211',
                                 parts: [

                                 ]
                            }
                        ]
                  }
            ]
      }
   ]
}

考虑到我可能需要在汽车阵列的任何级别插入一个对象,最好的方法是什么?

我无力的尝试:

 const updatePart = (id, obj, car) => {
    for (var i = 0; i < car.length; i++) {
        if (car[i].id == id) {
            car[i].parts.push(obj)
        } else {
            car[i].parts.map(function (item) {
                updatePart(id, obj, item)
            })
        }
        return car
    }
}

car = updateTree(id, obj, car);

如果您想获得一个新数组,您可以使用新的parts属性映射对象。

 const update = (array, id, object) => array.map(o => o.id === id ? { ...o, parts: [...o.parts, object] } : { ...o, parts: update(o.parts, id, object) } ); var car = [{ id: 13, title: 'Component13', parts: [{ id: 784, title: 'Component242', parts: [] }, { id: 9, type: 'mitigation', parts: [{ id: 68, type: 'mitigation22', parts: [] }, { id: 88, type: 'threat', parts: [] }] }] }, { id: 3, title: 'Component13', parts: [{ id: 60, title: 'Component34', parts: [] }, { id: 51, type: 'threat', parts: [{ id: 38, type: 'mitigation22', parts: [] }] }] }], result = update(car, 38, { id: 34, title: 'Component211', parts: [] }); console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

如果找到id则采用短路的变异方法。

 const update = (array, id, object) => array.some(o => o.id === id ? o.parts.push(object) : update(o.parts, id, object) ); var car = [{ id: 13, title: 'Component13', parts: [{ id: 784, title: 'Component242', parts: [] }, { id: 9, type: 'mitigation', parts: [{ id: 68, type: 'mitigation22', parts: [] }, { id: 88, type: 'threat', parts: [] }] }] }, { id: 3, title: 'Component13', parts: [{ id: 60, title: 'Component34', parts: [] }, { id: 51, type: 'threat', parts: [{ id: 38, type: 'mitigation22', parts: [] }] }] }]; update(car, 38, { id: 34, title: 'Component211', parts: [] }); console.log(car);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

也许考虑一个查找对象来存储对树中节点的引用的平面列表:

let memo = {};
const buildMemo = (arr) => {
  arr.forEach(item => {
    memo[item.id] = item;
    if (item.parts) buildMemo(item.parts);
  }
};
buildMemo(car);

现在,如果您需要对 id = 34 的car树节点进行一些操作,您可以从 memo[34] 中获取引用。 如果您从car阵列中添加/删除/移动节点,您将需要逻辑来更新备忘录

您的updatePart需要一个数组,但在您的map您使用的是递归发送对象。 所以你根本不需要使用map (或forEach ,这里最适合):

 var car=[{id:13,title:"Component13",parts:[{id:784,title:"Component242",parts:[]},{id:9,type:"mitigation",parts:[{id:68,type:"mitigation22",parts:[]},{id:88,type:"threat",parts:[]}]}]},{id:3,title:"Component13",parts:[{id:60,title:"Component34",parts:[]},{id:51,type:"threat",parts:[{id:38,type:"mitigation22",parts:[]}]}]}]; const updatePart = (id, obj, car) => { for (var i = 0; i < car.length; i++) { console.log(car[i]) if (car[i].id == id) { car[i].parts.push(obj) } else { updatePart(id, obj, car[i].parts) } } return car } const obj = { id: 34, title: 'Component211', parts: [ ] } car = updatePart(38, obj, car); console.log(car)

您的代码中的其他错误是return car inside loop,您应该在循环完成后返回并且您声明updatePart不是updateTree

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM