John Stuart
John Stuart

Reputation: 1150

Remove Object inside Array inside another Array Javascript

let bigArray = [
{
    Name: 'Alice',
    children: [
                 {Name: 'AliceChild1', Country: 'country1'}, 
                 {Name: 'AliceChild2', Country: 'country2'}
    ]
},
{
    Name: 'Bob',
    children: [
                 {Name: 'BobChild1', Country: 'country3'}, 
                 {Name: 'BobChild2', Country: 'country4'}
    ]
},
{
    Name: 'Sam',
    children: [
                 {Name: 'SamChild1', Country: 'country5'}, 
                 {Name: 'SamChild2', Country: 'country6'}
    ]
},
]

I want to remove an object from array inside another array. Property Name is unique. For an example if BobChild2 is removed bigArray should return as

let bigArray = [
{
    Name: 'Alice',
    children: [
                 {Name: 'AliceChild1', Country: 'country1'}, 
                 {Name: 'AliceChild2', Country: 'country2'}
    ]
},
{
    Name: 'Bob',
    children: [
                 {Name: 'BobChild1', Country: 'country3'},
    ]
},
{
    Name: 'Sam',
    children: [
                 {Name: 'SamChild1', Country: 'country5'}, 
                 {Name: 'SamChild2', Country: 'country6'}
    ]
},
]

What is the best way to do this in JavaScript ?

Updated: My answer

function removeChild(bigArray, childName) {
  let copyBigArray = []
  bigArray.forEach((item) => {
    let Obj = {
      Name: item.Name,
      children: item.children.filter(c => c.Name !== childName)
    }
    copyBigArray.push(Obj)
  })
  return copyBigArray
}

Upvotes: 0

Views: 93

Answers (5)

faramarz razmi
faramarz razmi

Reputation: 279

Try this way:

let bigArray = [{
    Name: 'Alice',
    children: [{
        Name: 'AliceChild1',
        Country: 'country1'
      },
      {
        Name: 'AliceChild2',
        Country: 'country2'
      }
    ]
  },
  {
    Name: 'Bob',
    children: [{
        Name: 'BobChild1',
        Country: 'country3'
      },
      {
        Name: 'BobChild2',
        Country: 'country4'
      }
    ]
  }
]


bigArray.forEach(function(o) {
  o.children = o.children.filter(s => s.Name != 'BobChild2');
});

console.log(bigArray);

Upvotes: 1

Erfan Bahramali
Erfan Bahramali

Reputation: 412

A main loop for the initial values of the array

Another loop for children values

The first parameter is the array itself that wants to be filtered, for example: bigArray

The second parameter is the value for the filter, for example: BobChild2

The third parameter is the key for the filter, for example: Name

let bigArray = [{
        Name: 'Alice',
        children: [
            { Name: 'AliceChild1', Country: 'country1' },
            { Name: 'AliceChild2', Country: 'country2' }
        ]
    },
    {
        Name: 'Bob',
        children: [
            { Name: 'BobChild1', Country: 'country3' },
            { Name: 'BobChild2', Country: 'country4' }
        ]
    },
    {
        Name: 'Sam',
        children: [
            { Name: 'SamChild1', Country: 'country5' },
            { Name: 'SamChild2', Country: 'country6' }
        ]
    },
];

function filterBigArray(array, value, filter) {
    let result = [];
    bigArray.forEach(person => {
        let childs = [];
        person.children.forEach(children => {
            if (children[filter] !== value) {
                childs.push(children);
            }
        });
        result.push(childs);
    });
    return result;
}
let res = filterArray(bigArray, 'BobChild2', 'Name');
console.log(res);

You can also filter different keys, for example:

let res = filterBigArray(bigArray, 'country3', 'Country');
console.log(res);

Upvotes: 0

Filip Huhta
Filip Huhta

Reputation: 2368

Here is an example how you could achieve it:

let bigArray = [
{
    Name: 'Alice',
    children: [
                 {Name: 'AliceChild1', Country: 'country1'}, 
                 {Name: 'AliceChild2', Country: 'country2'}
    ]
},
{
    Name: 'Bob',
    children: [
                 {Name: 'BobChild1', Country: 'country3'}, 
                 {Name: 'BobChild2', Country: 'country4'}
    ]
},
{
    Name: 'Sam',
    children: [
                 {Name: 'SamChild1', Country: 'country5'}, 
                 {Name: 'SamChild2', Country: 'country6'}
    ]
},
]


function filterName(name, data) {
  return data.reduce((arr, item) => {
    if (item.Name != name) {
      if (item.children) item.children = filterName(name, item.children)
      arr.push(item)
    }
    return arr  
  }, [])
}

console.log(filterName("BobChild2", bigArray));

Upvotes: 0

tsnkff
tsnkff

Reputation: 806

Well the structure isn't optimal because it'll require iterating over 2 arrays, but I'd use filter() (documentation) something like this:

function deepFilter(array, name) {
  return array.map(arr => {
     if (!arr || !arr.children) {
       return arr;
     }
     arr.children = arr.children.filter(c => c.Name !== name);
     return arr;
  })
}

Filter has to return a Boolean to know if the element should be returned or not. Map has to return an element.

If you want to remove an element from the first Array once its children are empty, you could replace the map by a filter.

function deepFilter(array, name) {
  return array.filter(arr => {
     if (!arr || !arr.children || !arr.children.length) {
       return false;
     }
     arr.children = arr.children.filter(c => c.Name !== name);
     return arr && arr.children && arr.children.length;
  })
}

--

Use them by doing:

const new = deepFilter(bigArray, 'SamChild1')

Upvotes: 0

Chrillewoodz
Chrillewoodz

Reputation: 28348

To support any nested depth you can do something like this:

function searchAndRemove(arr, query) {

    for (var i = arr.length; i > 0; i--) {

        if (query == arr[i].Name) {
            arr.splice(i, 1);
        }
    }
        
    if (arr.children) {
        searchAndRemove(arr.children, query);
    }
}

searchAndRemove(bigArray, 'BobChild2');

This will go through your array recursively until it finds all occurrences of BobChild2 and removes them.

Upvotes: 0

Related Questions