devedvdevdev
devedvdevdev

Reputation: 93

js - comparing 2 arrays of objects, and storing the identical and the unidentical results in new arrays

Made example arrays -

const arr = [
  {
    name: "q",
    age: 10,
    size: "M",
  },
  {
    name: "w",
    age: 10,
    size: "S",
  },
  {
    name: "e",
    age: 10,
    size: "M",
  },
];

const arr2 = [
  {
    name: "q",
    age: 10,
    size: "M",
  },
  {
    name: "w",
    age: 10,
    size: "S",
  },
  {
    name: "i",
    age: 10,
    size: "S",
  },
  {
    name: "x",
    age: 10,
    size: "S",
  },
];

I want to compare the first array (arr) to the second one (arr2) by specific properties in the example case name and size.

If it's a match then I want to store the results in a new array and if it's unmatched then I want to store the results in another array, so I'll get 2 arrays at the end.

What I tried -

   for (let j = 0; j < arr2.length; j++) {
  for (let i = 0; i < arr.length; i++) {
    const { name: name1, size: size1 } = arr[i];
    const { name: name2, size: size2 } = arr2[j];

    
    if (name1 === name2 && size1 === size2) {
        x.push(arr.splice(i, 1)[0]);
        break;
    } else {
        y.push(arr[i]);
    }
  }
}

Got in x -

[ { name: 'q', age: 10, size: 'M' },   { name: 'w', age: 10, size: 'S' } ]

Got in y -

[ { name: 'e', age: 10, size: 'M' },
  { name: 'e', age: 10, size: 'M' } ]

I should get in y -

[ { name: 'e', age: 10, size: 'M' } ]

Would love to get some help

Upvotes: 0

Views: 43

Answers (1)

trincot
trincot

Reputation: 350760

Your inner loop cannot decide whether an element should be pushed to y, because not all values of arr2 have been iterated yet. Such a push can only happen when all those arr2 values have been considered.

As you don't remove the item from arr when it is pushed to y, it is no surprise it can be pushed a second time.

It is also problematic that you use splice in a loop over that same array. This means that indexes are skipped, and this could also be a source of wrong results.

One way to solve this, is to create a Set of the second array, of strings that uniquely define the name/size combination, for instance by joining them with a separator that will not occur in the size value. Then remains to iterate the first array and check if that name/size key is present in that set or not:

const arr = [{name: "q",age: 10,size: "M",},{name: "w",age: 10,size: "S",},{name: "e",age: 10,size: "M",},];
const arr2 = [{name: "q",age: 10,size: "M",},{name: "w",age: 10,size: "S",},{name: "i",age: 10,size: "S",},{name: "x",age: 10,size: "S",},];

const set = new Set(arr2.map(({name, size}) => size + "/" + name));

const x = [], y = [];
for (let obj of arr) {
    (set.has(obj.size + "/" + obj.name) ? x : y).push(obj);
}

console.log("x:");
console.log(x);
console.log("y:");
console.log(y);

Upvotes: 1

Related Questions