如何从对象的嵌套数组中递归删除特定对象? [英] how to delete specific object from nested array of objects recursively?

查看:473
本文介绍了如何从对象的嵌套数组中递归删除特定对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数据:

    var data = [ 
   { 
      "name":"list1",
      "type":"list",
      "id":1,
      "child":[ 
         { 
            "name":"list2",
            "type":"subList",
            "id":2,
            "child":[ 
               { 
                  "name":"list3",
                  "type":"subList",
                  "id":3
               },
               { 
                  "name":"list4",
                  "type":"list",
                  "id":4,
                  "child":[ 
                     { 
                        "name":"list5",
                        "type":"list",
                        "id":5
                     }
                  ]
               }
            ]
         },
         { 
            "name":"list6",
            "type":"subList",
            "id":6
         }
      ]
   },
   { 
      "name":"list I",
      "type":"list",
      "id":7
   }
]

我需要删除"id":5 ,从此数据中删除,我尝试过:

I need to remove "id": 5 form this data, I tried this :

data.filter(function f(o) {
  return o.id !== 5 ||
         o.child && (o.child.filter(f)).length
})

最终输出将没有id:5,在某些情况下,第一个列表id:1也可以删除.递归简化此操作很热门它可能没有N个子级列表,必须遍历每个列表并将其删除?

Final output would be without id:5, In some cases the first list id:1 also can be erasable. Hot to simplify this recursively It may have N no of children list, have to loop through every list and delete it?

推荐答案

没有简单(非hacky)方法来删除元素而不循环遍历数组.

There is no easy (non-hacky) way to remove the element without looping through the arrays.

您需要先过滤数据数组,然后映射其余条目并递归过滤其child属性,例如:

You need to first filter the data array, then map over the remaining entries and filter their child property recursively, e.g.:

function removeIdDeep(data, idToRemove) {
  const filtered = data.filter(entry => entry.id !== idToRemove);
  return filtered.map(entry => {
    if(!entry.child) return entry;
    return {...entry, child: removeIdDeep(entry.child, idToRemove)};
  });
}

var data = [ { "name":"list1", "type":"list", "id":1, "child":[ { "name":"list2", "type":"subList", "id":2, "child":[ { "name":"list3", "type":"subList", "id":3 }, { "name":"list4", "type":"list", "id":4, "child":[ { "name":"list5", "type":"list", "id":5 } ] } ] }, { "name":"list6", "type":"subList", "id":6 } ] }, { "name":"list I", "type":"list", "id":7 } ];

function removeIdDeep(data, idToRemove) {
  const filtered = data.filter(entry => entry.id !== idToRemove);
  return filtered.map(entry => {
    if(!entry.child) return entry;
    return {...entry, child: removeIdDeep(entry.child, idToRemove)};
  });
}

console.log(removeIdDeep(data, 5));

如果要在删除元素之前提示用户,只需将confirm提示添加到过滤器中即可:

If you want to prompt the user before removing elements, you can just add the confirm prompt to the filter:

var data = [ { "name":"list1", "type":"list", "id":1, "child":[ { "name":"list2", "type":"subList", "id":2, "child":[ { "name":"list3", "type":"subList", "id":3 }, { "name":"list4", "type":"list", "id":4, "child":[ { "name":"list5", "type":"list", "id":5 } ] } ] }, { "name":"list6", "type":"subList", "id":6 } ] }, { "name":"list I", "type":"list", "id":7 } ];

function removeIdDeep(data, idToRemove) {
  const filtered = data.filter(entry => {
    if(entry.id === idToRemove) {
      const numChilds = entry.childs ? entry.childs.length : 0;
      return !confirm(`Are you sure you want to delete ${entry.name}? It contains ${numChilds} children.`);
    }
    return true;
  });
  return filtered.map(entry => {
    if(!entry.child) return entry;
    return {...entry, child: removeIdDeep(entry.child, idToRemove)};
  });
}

console.log(removeIdDeep(data, 5));

如果要显示一些自定义警告,则必须首先找到该元素,显示警告,然后才调用removeIdDeep.

If you want to display some custom warning, you'll have to first find the element, display the warning and only then call removeIdDeep.

这篇关于如何从对象的嵌套数组中递归删除特定对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆