ees3
ees3

Reputation: 105

Remove element from array inside array of objects if present in another array of objects

I am working with a large array of objects. I have simplified my data structure to the following. Each object has an id and each id has two arrays associated with it type1 and type2.

const arr = [{id: "12345", type1: ["Hat 1", "Hat 3"], type2: ["Hat 2", "Glove 4"]}, 
             {id: "12345", type1: ["Glove 1", "Hat 1"], type2: ["Glove 3", "Hat 2"]},           
             {id: "54321", type1: ["Jacket 1", "Hat 4"], type2: ["Hat 3", "Hat 4"]},
             {id: "54321", type1: ["Glove 2", "Hat 2"], type2: ["Glove 3", "Jacket 4"]},
             {id: "13579", type1: ["Hat 1", "Hat 2"], type2: ["Hat 3", "Hat 4"]},
             {id: "13579", type1: ["Glove 1", "Glove 2"], type2: ["Glove 3", "Glove 4"]}]

I have a "lookup" array of objects. Each object has an id and a title

const lookup = [{id: "12345", title: "Hat 1"},
                {id: "12345", title: "Hat 2"},
                {id: "12345", title: "Glove 3"},
                {id: "54321", title: "Hat 3"} 
                {id: "54321", title: "Jacket 4"},
                {id: "54321", title: "Glove 5"},
                {id: "13579", title: "Hat 2"},
                {id: "13579", title: "Jacket 3"}]

I need to use the "lookup" object for any matching id that has a title I need to remove it from type1 or type2 or both. So my resulting array of objects would look something like so

const result = [{id: "12345", type1: ["Hat 3"], type2: ["Glove 4"]}, 
                {id: "12345", type1: ["Glove 1"], type2: []},           
                {id: "54321", type1: ["Jacket 1", "Hat 4"], type2: ["Hat 4"]},
                {id: "54321", type1: ["Glove 2", "Hat 2"], type2: ["Glove 3"]},
                {id: "13579", type1: ["Hat 1"], type2: ["Hat 3", "Hat 4"]},
                {id: "13579", type1: ["Glove 1", "Glove 2"], type2: ["Glove 3", "Glove 4"]}]

The duplicates and having to search through both arrays for any matching id's is confusing me. Is there a simple way to do this or maybe a better way to structure the data so it's not so convoluted?

Upvotes: 0

Views: 109

Answers (2)

Koushik Chatterjee
Koushik Chatterjee

Reputation: 4175

Let's not mutate the original data, and create a new resultant array. you can use map, filter and some of Array

arr.map(({id, type1, type2}) => ({
    id,
    type1: type1.filter(t => !lookup.some(l => id===l.id && l.title === t)),
    type2: type2.filter(t => !lookup.some(l => id===l.id && l.title === t))
}));

Here is an working example:

const arr =[
     {id: "12345", type1: ["Hat 1", "Hat 3"], type2: ["Hat 2", "Glove 4"]}, 
     {id: "12345", type1: ["Glove 1", "Hat 1"], type2: ["Glove 3", "Hat 2"]},           
     {id: "54321", type1: ["Jacket 1", "Hat 4"], type2: ["Hat 3", "Hat 4"]},
     {id: "54321", type1: ["Glove 2", "Hat 2"], type2: ["Glove 3", "Jacket 4"]},
     {id: "13579", type1: ["Hat 1", "Hat 2"], type2: ["Hat 3", "Hat 4"]},
     {id: "13579", type1: ["Glove 1", "Glove 2"], type2: ["Glove 3", "Glove 4"]}
  ],
  lookup = [
     {id: "12345", title: "Hat 1"},
     {id: "12345", title: "Hat 2"},
     {id: "12345", title: "Glove 3"},
     {id: "54321", title: "Hat 3"}, 
     {id: "54321", title: "Jacket 4"},
     {id: "54321", title: "Glove 5"},
     {id: "13579", title: "Hat 2"},
     {id: "13579", title: "Jacket 3"}
  ],
  res = arr.map(({id, type1, type2}) => ({
	  id,
	  type1: type1.filter(t => !lookup.some(l => id===l.id && l.title === t)),
	  type2: type2.filter(t => !lookup.some(l => id===l.id && l.title === t))
  }));
  
  console.log(res);

Upvotes: 1

SubSul
SubSul

Reputation: 2563

Loop through arr and for each entry of arr, loop through lookup to compare and modify arr

  for(let arrEntry of arr) {
    let id = arrEntry.id;
    let type1 = arrEntry.type1;
    let type2 = arrEntry.type2;

    for(let lookupEntry of lookup) {
      let title = lookupEntry.title;
      if(lookupEntry.id === id && type1.includes(title)) {
        type1.splice(type1.indexOf(title), 1);
      }
      if(lookupEntry.id === id && type2.includes(title)) {
        type2.splice(type2.indexOf(title), 1);
      }
    }
  }

  console.log(arr)

Upvotes: 1

Related Questions