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从一维数组中删除相关项的主要内容,如果未能解决你的问题,请参考以下文章

js中多维数组转一维

js中多维数组转一维

Numpy - 从一维数组中删除最后一个元素的最佳方法?

C语言一维数组中如何查找指定元素?

php中一维或多维数组去除重复项

请问C语言中数字一维数组转换二维数组通项公式?