MarcoLe
MarcoLe

Reputation: 2509

Javascript - remove object out of nested Object array

I have a nested Object array and I would like to remove an item out of this nested array, but for some reason this does not seem to work with my approach:

Object

export const completeNavigationItemsV2Response = [
    {
        id: 'Erlebniskategorien',
        title: 'Erlebniskategorien',
        uri: '/on/demandware.store/Sites-JSShop-Site/default/SearchJS-Show',
        children: [
            {
                id: 'fliegen-fallen',
                title: 'Fallen & Springen',
                uri: '/fliegen-fallen/fallen-springen,default,sc.html',
                children: [
                    {
                        id: 'fallen-springen',
                        title: 'Fallen & Springen',
                        uri: '/fliegen-fallen/fallen-springen,default,sc.html',
                        children: [],
                    }
                ],
            },
            {
                id: 'Weit-Weg',
                title: 'Reisen & Kurzurlaub',
                uri: '/reisen/Weit-Weg,default,sc.html',
                children: [
                    {
                        id: 'staedtereisen',
                        title: 'Städtereisen',
                        uri: '/reisen/staedtereisen,default,sc.html',
                        children: [],
                    }
                ],
            },
            {
                id: 'motorpower',
                title: 'Motorpower',
                uri: '/geschenke-maenner/motorpower,default,sc.html',
                children: [
                    {
                        id: 'rennwagen',
                        title: 'Rennwagen',
                        uri: '/motorpower/rennwagen,default,sc.html',
                        children: [],
                    }
                ],
            },
            {
                id: '10',
                title: 'Erlebnisse mit Stars',
                uri: '/erlebnisse-mit-stars/l/10',
                children: [
                    {          // <== remove this object with id === 'glossar'
                        id: 'glossar', 
                        title: 'Glossar',
                        uri: '/erlebnisstandorte/glossar,default,pg.html',
                        children: [],
                    },
                ],
            },
        ],
    }
];

Does someone of you would now a handy es6 way how to remove that subObject from the whole object in a somewhat dynamic way like with the .map() or .filter() function?

Upvotes: 1

Views: 418

Answers (2)

MauriceNino
MauriceNino

Reputation: 6757

If you want it for any level in your object, you could do it with a recursive function like so:

// Object is the same, just minified
const completeNavigationItemsV2Response=[{id:"Erlebniskategorien",title:"Erlebniskategorien",uri:"/on/demandware.store/Sites-JSShop-Site/default/SearchJS-Show",children:[{id:"fliegen-fallen",title:"Fallen & Springen",uri:"/fliegen-fallen/fallen-springen,default,sc.html",children:[{id:"fallen-springen",title:"Fallen & Springen",uri:"/fliegen-fallen/fallen-springen,default,sc.html",children:[]}]},{id:"Weit-Weg",title:"Reisen & Kurzurlaub",uri:"/reisen/Weit-Weg,default,sc.html",children:[{id:"staedtereisen",title:"Städtereisen",uri:"/reisen/staedtereisen,default,sc.html",children:[]}]},{id:"motorpower",title:"Motorpower",uri:"/geschenke-maenner/motorpower,default,sc.html",children:[{id:"rennwagen",title:"Rennwagen",uri:"/motorpower/rennwagen,default,sc.html",children:[]}]},{id:"10",title:"Erlebnisse mit Stars",uri:"/erlebnisse-mit-stars/l/10",children:[{id:"glossar",title:"Glossar",uri:"/erlebnisstandorte/glossar,default,pg.html",children:[]}]}]}];


const removeItemWithId = (array, id) => {
  return array
    .filter(obj => obj.id !== id) // filter out if the id matches
    .map(obj => ({ // Do the same for children (if they exist)
      ...obj,
      children: obj.children !== undefined 
                              ? removeItemWithId(obj.children, id) 
                              : undefined
    }));
};

console.log(removeItemWithId(completeNavigationItemsV2Response, 'glossar'));

Upvotes: 2

Nick Parsons
Nick Parsons

Reputation: 50974

Although newer than ES6, if you can support .flatMap(), you can do this recursively by calling .flatMap() on your initial array and then calling it on your children array. If you reach the element which you want to remove, you can return an empty array [], which will remove the object when concatenated into the resulting array.

const arr = [{ id: 'Erlebniskategorien', title: 'Erlebniskategorien', uri: '/on/demandware.store/Sites-JSShop-Site/default/SearchJS-Show', children: [{ id: 'fliegen-fallen', title: 'Fallen & Springen', uri: '/fliegen-fallen/fallen-springen,default,sc.html', children: [{ id: 'fallen-springen', title: 'Fallen & Springen', uri: '/fliegen-fallen/fallen-springen,default,sc.html', children: [], }], }, { id: 'Weit-Weg', title: 'Reisen & Kurzurlaub', uri: '/reisen/Weit-Weg,default,sc.html', children: [{ id: 'staedtereisen', title: 'Städtereisen', uri: '/reisen/staedtereisen,default,sc.html', children: [], }], }, { id: 'motorpower', title: 'Motorpower', uri: '/geschenke-maenner/motorpower,default,sc.html', children: [{ id: 'rennwagen', title: 'Rennwagen', uri: '/motorpower/rennwagen,default,sc.html', children: [], }], }, { id: '10', title: 'Erlebnisse mit Stars', uri: '/erlebnisse-mit-stars/l/10', children: [{ id: 'glossar', title: 'Glossar', uri: '/erlebnisstandorte/glossar,default,pg.html', children: [], }, ], }, ], }];

const removeId = "glossar";
const res = arr.flatMap(function fn(o) {
  return o.id !== removeId ? ({...o, children: o.children.flatMap(fn)}) : [];
});

console.log(res);

Upvotes: 1

Related Questions