Person
Person

Reputation: 2259

Remove each element of array from subarrays of objects?

I have an array of objects with this structure

const arr = [{
  id: 0,
  name: 'string'
}, {
  id: 1,
  name: 'string'
}]

I also have main array

const mainArray = [{
    items: [{
      id: 0,
      name: 'string'
    }]
  },
  {
    items: [{
        id: 5,
        name: 'string'
      },
      {
        id: 3,
        name: 'string'
      }
    ]
  }
];

I'm displaying every item in items arrays from mainArray on the screen. What I want to do is remove every item of arr from every items array of mainArray and show updated mainArray on the screen.

I was thinking doing something like this

mainArray = mainArray.map((e) => {
      e.items = e.items.filter((el) => {
        return !arr.includes( el );
      });
  }); 

This returns an error Cannot read property 'items' of undefined

Or something like this

mainArray = mainArray.filter((e) => {
        return !arr.includes( e.items );
  });

But this also doesn't work.

All the help will be appreciated.

Upvotes: 3

Views: 60

Answers (2)

vsync
vsync

Reputation: 130075

As I've said in the comments, you cannot use const keyword and override the variable later. but, you don't event need to, since you can modify the inner properties without a problem:

const arr = [
  { id:0, name:'string' }, 
  { id:1, name:'string' }
]

const mainArray = [{
    items: [{ id:0, name:'string' },]
  },
  {
    items: [
      { id:5, name:'string' },
      { id:3, name:'string' },
      { id:1, name:'string' },
    ]
  }
];


// for each "items" item, check if its "id" exists in the "arr" Array, so 
// I like to use "some" Array method for that:
mainArray.map((e) => {
    e.items = e.items.filter(el => !arr.some(needle => needle.id == el.id))
}); 

console.log( mainArray )

Upvotes: 1

epascarello
epascarello

Reputation: 207501

I would map the used ids into an array for easier look up. That it is a foreach loop over the main array items, and than filter using includes to see if the item is in the array.

const arr = [{
  id: 0,
  name: 'string'
}, {
  id: 1,
  name: 'string'
}]

const mainArray = [{
    items: [{
      id: 0,
      name: 'string'
    }]
  },
  {
    items: [{
        id: 5,
        name: 'string'
      },
      {
        id: 3,
        name: 'string'
      }
    ]
  }
];

// map ids into a look up array so we do not 
// have to loop over objects every time
const usedIds = arr.map(o => o.id);

// Loop over main array so we can access each object
mainArray.forEach(sa => {
  // replace items with a filtered array
  // filter checks to see if the id is not used
  sa.items = sa.items.filter(o => !usedIds.includes(o.id))
})

console.log(mainArray)

Upvotes: 0

Related Questions