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))