js从一维数组中删除相关项
Posted
技术标签:
【中文标题】js从一维数组中删除相关项【英文标题】:js remove related items from one dimensional array 【发布时间】:2021-08-24 17:16:38 【问题描述】:我有一个可能看起来像这样的对象数组:
name: "A", parent: null,
name: "B", parent: "A",
name: "C", parent: "B",
name: "D", parent: "B",
name: "E", parent: "A",
这里是树形层次结构:
-A
-B
-C
-D
-E
我试图从数组中删除名称为“B”的所有项目(这也应该删除其子项,因此在这种情况下项目“C”和“D”,但是我是递归新手,我是无法自己完成这项工作,有人可以告诉我这样做的最佳方式吗?
感谢任何愿意提前提供帮助的人
【问题讨论】:
您只需使用forEach
就可以做到这一点
@Goubermouche,这里有一个相关的question和answer
这是如何渲染的?
使用delete object.property
,它将删除该属性(如果它是嵌套对象,那么该对象也是)
@evolutionxbox 尚未渲染它,我只是想删除一个项目及其所有“孩子”
【参考方案1】:
var array_of_object = [
name: "A", parent: null,
name: "B", parent: "A",
name: "C", parent: "B",
name: "D", parent: "B",
name: "E", parent: "A",
];
//returns array with updated value.
function deleteElementIncludingItsChildren(children, OriginalArray)
return OriginalArray.filter(function(element)
//console.log(element)
if(element.name == children || element.parent == children) return false;
else return element;
);
console.log(deleteElementIncludingItsChildren("B", array_of_object))
更新: 用于删除特定节点及其所有子节点
var arr = [
name: "A", parent: null,
name: "B", parent: "A",
name: "C", parent: "B",
name: "D", parent: "B",
name: "E", parent: "A",
];
function rm(node)
var tmp = [];
for(var i = 0; i<arr.length; i++)
if(node == arr[i].parent)
tmp.push(arr[i].name);
if(node==arr[i].name)
arr.splice(i, 1);
i--;
if(tmp.length !==0)
tmp.forEach(function(elem)
rm(elem);
);
rm("B")
console.log(arr)
【讨论】:
这个函数很好用,但它“看起来”只有 2 层深 - 所以如果我们使用我发送的数组作为示例,它似乎可以工作,但是,当我(例如)尝试删除名为“A”的项目会删除前两个级别中的所有内容(因此“C”和“D”仍保留在数组中)。有没有办法解决这个问题?【参考方案2】:编写此代码的一种方法是将其置于另一个函数之上,该函数收集捕获后代层次结构的节点列表。那就是直接递归,然后main函数就是简单的过滤:
const desc = (target, xs, node = xs .find ((name) => name == target)) => node ? [
node,
... xs .filter ((parent) => parent == node .name) .flatMap ((name) => desc (name, xs))
] : []
const removeHier = (target, xs, h = desc (target, xs)) =>
xs .filter (x => ! h.includes (x))
const records = [name: "A", parent: null, name: "B", parent: "A", name: "C", parent: "B", name: "D", parent: "B", name: "E", parent: "A", name: "F", parent: "D"]
console .log (removeHier ('B', records))
【讨论】:
【参考方案3】:解决这个问题的一种方法:
对图进行深度优先遍历并记录/建立每个元素的祖先。如果您正在检查一个叶节点并且它有 B 作为祖先或者是 B 本身,它必须离开。
深度优先:每次看到一个子元素时,对所有这些子元素重复该函数/算法。 叶节点:没有任何子节点的对象。
如何建立父子关系?
当你处理所有的元素时,将你以前没有见过的每一个都放入一个字典(也就是 JS 中的 hashmap、set 或普通对象)中,使用对象的名称作为字典键。当您遇到具有给定父对象的事物时,只需检查您的字典中是否已经存在该对象,并将当前元素添加为子元素。
如果树非常大,这种方法可能会占用大量内存,因此您可能希望将自己限制为仅从子对象对父对象进行单个引用,而不是每个父对象都指向其所有子对象。
【讨论】:
【参考方案4】:如何删除所有嵌套的子项
function deleteAll (obj , arr)
function DeleteNode (obj)
let no = [];
for(let i = 0 ;i < obj.length ; i++)
for(let j = 0 ;j < arr.length ; j++)
if(arr[j].parent === obj[i])
no.push(arr[j].name);
if(obj[i] === arr[j].name)
arr.splice(j,1);
j--
if(no.length > 0)
DeleteNode(no , arr)
DeleteNode(obj)
return arr ;
// Question
const arr = [name: "A", parent: null,
name: "B", parent: "A",
name: "C", parent: "B",
name: "D", parent: "B",
name: "E", parent: "A"];
console.log(deleteAll (["B"] , arr))
如何创建节点
const arr = [name: "A", parent: null,
name: "B", parent: "A",
name: "C", parent: "B",
name: "D", parent: "B",
name: "E", parent: "A"];
//first create a parent oblect
function createTree (arr)
let parent = arr.filter((el)=>return el.parent === null);
let children = arr.filter((el)=>return el.parent !== null);
let tree = ;
//start
children.forEach((c)=>
let parent = c.name ;
let step = [];
let responceFindParent =
function find(parent,arr)
let a= null;
arr.forEach((el)=>
if(el.name === parent)
a= el
)
if(a.parent === null)
step.push(a.name);
let r =el:a , step:step
responceFindParent = r
return ;
else
step.push(a.name)
find(a.parent , arr)
find(parent,arr)
let stepArr = responceFindParent.step.reverse();
function insert (tree)
let b = stepArr[0]
if(!(stepArr[0] in tree))
tree[stepArr[0]] =
stepArr.splice(0,1)
if(stepArr . length > 0)
insert(tree[b])
insert (tree)
//end
)
return tree
console.log(createTree (arr))
【讨论】:
问题是关于删除“分支”,而不仅仅是构建图表。但我想这是一个开始 而且很容易删除分支而不构建整个图。在此处查看其他一些答案。 非常抱歉,我误解了这个问题,现在我已经更新了答案,请查看..以上是关于js从一维数组中删除相关项的主要内容,如果未能解决你的问题,请参考以下文章