3

For example, how do I check if ALL the objects in array2 exist in array1 based on their id?

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
const array2 = [{ id: 1 }, { id: 2 }]

For some reason, I couldn't find the solution on Google.

I thought about this:

const result = array1.every(obj1 => {
  // what do use here? includes? contains?
})

console.log(result)

But I'm kind of stuck in the middle of the code. The most logical solution to me was to use includes. However, includes doesn't seem to take a function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes. So I'm not sure if I can check the objects by id.

alex
  • 7,111
  • 15
  • 50
  • 77

5 Answers5

4

includes will only be true if both objects are the same reference in memory, which is (probably) not the case. Instead, I'd create a Set of array1's ids initially, and then check to see if every array2 id is in the set. This way, you only have to iterate over array1 once, at the very beginning (Sets have O(1) lookup time):

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }];
const array2 = [{ id: 1 }, { id: 2 }];

const idSet = new Set(array1.map(({ id }) => id));
console.log(
  array2.every(({ id }) => idSet.has(id))
);

(Arrays do not have a contains function)

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
3
var matching = [];

for (var j = 0; j < array1.length; j++) {
    for (var i = 0; i < array2.length; i++) {
        if (array2[i].id === array1[j].id) {
            matching.push(array2[i].id);       
        }
    }
}

if (array2.length === matching.length) {
    console.log("All elements exist");
} else {
    console.log("One or more of the elements does not exist");
}
Snezhana
  • 31
  • 1
2

Like this, using Array.prototype.every in combination with Array.prototype.some():

const result = array2.every(o2 => array1.some(o1 => o1.id === o2.id));

This will check if every element in array2 has a matching element in array1.


Here's a complete snippet:

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }];
const array2 = [{ id: 1 }, { id: 2 }];

const result = array2.every(o2 => array1.some(o1 => o1.id === o2.id));

console.log(result);

If array1 is large, or used repeatedly to perform this operation, the Set-based approach proposed in other answers is more optimized.

Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
2

Similar type of question is already asked. You can refer that also on this link Check if every element in one array is in a second array

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }];
const array2 = [{ id: 1 }, { id: 2 }];

let array1ids = array1.map(a => a.id);
const result = array2.every(a => array1ids.includes(a.id));
console.log(result);

const array3 = [{ id: 1 }, { id: 2 }, { id: 3 }];
const array4 = [{ id: 1 }, { id: 6 }];

let array3ids = array3.map(a => a.id);
const result2 = array4.every(a => array3ids.includes(a.id));
console.log(result2);
Karan
  • 12,059
  • 3
  • 24
  • 40
1

For large arrays, I recommend pre-processing the array that's used as the criteria to create a Set so that each check is an O(1) lookup and overall O(n) instead of O(n^2). This code makes a couple assumptions though, namely:

  • The criteria is based on a select() function of the object, its index in the array, and a reference to the array.
  • The selection used as the criteria returns a primitive and can perform an equality check identical to a Set using a === b || (a !== a && b !== b) (to deal with a and b being NaN)

const has = select => array => {
  const set = new Set(array.map(select))
  return (object, index, array) => set.has(select(object, index, array))
}

const hasId = has(({ id }) => id)
const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
const array2 = [{ id: 1 }, { id: 2 }]

const result1 = array1.every(hasId(array2))
const result2 = array2.every(hasId(array1))

console.log(result1)
console.log(result2)
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153