Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to create a tree component. But I dont know how remove a item recursively inside a tree.

Each item its created dinamically and I would like remove an item/branch of the tree in each level.

The problem is that when I select and item and has not children I have to find his parent and remove selected item. But If selected item has children, I have to find his parent, get all children of selected item, update all parentId of children, added to parent and remove selected item. Do all of that recursively and return updated array.

const data = [
  {id: 1, title: 'foo', children: [
    {id: 11, parentId: 1, title: 'bar',},
    {id: 12, parentId: 1, title: 'baz', children: [
      {id: 121, parentId: 12, title: 'qux'},
      {id: 122, parentId: 12, title: 'quz'}
    ]},
    {id: 13, parentId: 1, title: 'corge'}
  ]},
  {id: 2, title: 'grault'}
];

const id = 12;
console.log (removeElement(data, id));

Result should be:

const data = [
  {id: 1, title: 'foo', children: [
    {id: 11, parentId: 1, title: 'bar', children: [
      {id: 121, parentId: 11, title: 'qux'},
      {id: 122, parentId: 11, title: 'quz'}
    ]},
    {id: 13, parentId: 1, title: 'corge'}
  ]},
  {id: 2, title: 'grault'}
];
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
226 views
Welcome To Ask or Share your Answers For Others

1 Answer

Although this can be done in a single function, it's a lot cleaner and less repetitive if you write this with mutual recursion. Here we write two functions. One removes the element from an array, replacing it with any children it might have. The other processes a single object, removing the id from it (and from any of its children.) Our main function here is removeElement, which will call removeElementFromArray on our input if the initial data is an array or call it against any children if the initial data is a plain object.

const removeElementFromArray = (arr, id) =>
  arr .flatMap (
    o => o.id === id
      ? [... (o .children || []).map (o => removeElement (o, id))]
      : [removeElement (o, id)]
  )

const removeElement = (obj, id) => 
  Array .isArray (obj)
    ? removeElementFromArray (obj, id)
    : {... obj, ... (obj .children ? {children: removeElementFromArray (obj .children, id)} : {}) }


const data = [
  {id: 1, title: 'foo', children: [
    {id: 11, title: 'bar'},
    {id: 12, title: 'baz', children: [
      {id: 121, title: 'qux'},
      {id: 122, title: 'quz'}
    ]},
    {id: 13, title: 'corge'}
  ]},
  {id: 2, title: 'grault'}
];

console .log (removeElement (data, 121)) // 121 removed
console .log (removeElement (data, 12))  // 12 removed; 121 and 122 moved to 1
console .log (removeElement (data, 1))   // 1 removed; 11, 12, 13 moved to root
console .log (removeElement (data, 42))  // No change
.as-console-wrapper {min-height: 100% !important; top: 0}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...