js从一维数组中删除相关项
js remove related items from one dimensional array
我有一个对象数组,可能看起来像这样:
{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”,但是我对递归和我无法自己完成这项工作,有人可以告诉我一个最佳的方法吗?
感谢任何愿意提前提供帮助的人
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)
解决此问题的一种方法:
对图进行深度优先遍历并记录/建立每个元素的祖先。如果您正在检查叶节点并且它有 B 作为祖先或者 B 本身,它必须去。
深度优先:每次看到子元素时,对所有这些子元素重复函数/算法。
叶节点:没有任何子节点的对象。
如何建立亲子关系?
当你处理所有的元素时,将你以前没有见过的每一个元素放入一个字典(又名hashmap,集合,或者JS中的普通对象),使用对象的名称作为字典键。当您遇到具有给定父项的对象时,只需检查字典中是否已经存在该对象,并将当前元素添加为子项。
如果树非常大,这种方法可能会占用大量内存,因此您可能希望将自己限制为仅从子对象引用一个父对象,而不是每个父对象都指向它的所有子对象。
如何删除所有嵌套子项
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))
一种编写方法是将其置于另一个函数之上,该函数收集捕获后代层次结构的节点列表。那就是一个简单的递归,然后主要功能只是一个过滤:
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))
我有一个对象数组,可能看起来像这样:
{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”,但是我对递归和我无法自己完成这项工作,有人可以告诉我一个最佳的方法吗?
感谢任何愿意提前提供帮助的人
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)
解决此问题的一种方法:
对图进行深度优先遍历并记录/建立每个元素的祖先。如果您正在检查叶节点并且它有 B 作为祖先或者 B 本身,它必须去。
深度优先:每次看到子元素时,对所有这些子元素重复函数/算法。 叶节点:没有任何子节点的对象。
如何建立亲子关系?
当你处理所有的元素时,将你以前没有见过的每一个元素放入一个字典(又名hashmap,集合,或者JS中的普通对象),使用对象的名称作为字典键。当您遇到具有给定父项的对象时,只需检查字典中是否已经存在该对象,并将当前元素添加为子项。
如果树非常大,这种方法可能会占用大量内存,因此您可能希望将自己限制为仅从子对象引用一个父对象,而不是每个父对象都指向它的所有子对象。
如何删除所有嵌套子项
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))
一种编写方法是将其置于另一个函数之上,该函数收集捕获后代层次结构的节点列表。那就是一个简单的递归,然后主要功能只是一个过滤:
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))