Question: i've got array like this. Unlimited number of nesting possible

```
const myArray = [
  {
   id: 1, 
   children: [
              { 
                id: 3,
                children: []
              }
             ]
  },
  {
   id: 2, children: []
  }
]

```

Please, help me to remove any object by id and return new array without it.

Answer: 
The `recursiveRemove` function will recursively remove the elements from the array and return the new list.

The map function creates copy of the items in the array, you can remove the map if you do not need to retain the original array's sanity.

```
function recursiveRemove ( list, id ) {
    return list.map ( item => { return {...item} }).filter ( item => {
        if ( 'children' in item ) {
            item.children = recursiveRemove ( item.children, id );
        }
        return item.id !== id;
    });
}
const test1 = recursiveRemove ( myArray, 1);
const test2 = recursiveRemove ( myArray, 2);
const test3 = recursiveRemove ( myArray, 3);

```
It makes sense to me to separate out the recursive traversal and filtering from the actual details of removing a certain id. So I would write a more generic `filterDeep` function which keeps only those objects where a predicate is true, recursing into `children` nodes.

Then we can supply a predicate to it that checks whether an item matches a specific id. Or rather, since we're removing those that match, our predicate actually checks whether our node *doesn't match* the id.

This is an implementation of that idea:

```js
const filterDeep = (pred) => (xs) =>
  xs .flatMap (x => pred (x)
    ? [{... x, children: filterDeep (pred) (x .children || [])}] 
    : []
  )

const removeId = (id) =>  
  filterDeep (x => x.id !== id)

const myArray = [{id: 1, children: [{id: 3, children: []}]}, {id: 2, children: []}]

console .log (removeId (1) (myArray))
console .log (removeId (2) (myArray))
console .log (removeId (3) (myArray))
console .log (removeId (42) (myArray))
```

```css
.as-console-wrapper {min-height: 100% !important; top: 0}
```

This will include a `children` node even if the original didn't have one. If we wanted to include it only if there was one to begin with we could change it to something like this:

```js
const filterDeep = (pred) => (xs) =>
  xs .flatMap (x => pred (x) 
    ? [{
        ... x, 
        ... (x.children ? {children: filterDeep (pred) (x .children || [])} : {})
      }] 
    : []
  )

```

Or with a little more sophistication, we could choose to include a `children` node only when it's available in the parent and the results are non-empty. That's left as an exercise for the reader. :-)