Check if all elements in an array are present in another

I want to make a function to check if all elements in an array are present in another. I have tried to do this:

function includesAll (needles, haystack) {
  return needles.every((needle) => {
    return haystack.includes(needle)
  })
}

However, when I test for this function for the empty array as needles, like this: includesAll([], [1]), it returns true, whereas I'm expecting false (because [1].includes([]) returns false). Why does this happen? And can you write a correct function (one that reflects the behavior of include, but for an array instead of an element)?

Upvotes: 2

Views: 361

Answers (3)

zer00ne
zer00ne

Reputation: 43853

Read this at MDN

every acts like the "for all" quantifier in mathematics. In particular, for an empty array, it returns true. (It is vacuously true that all elements of the empty set satisfy any given condition.)

Upvotes: 1

trincot
trincot

Reputation: 349946

Your code is working as expected. The function should return true because there is no element in the empty needles array that is not included in the haystack.

You wrote:

because [1].includes([]) returns false

...but that is not the same, and is not happening either. The includes method is not passed the needles array, but elements in that array. And since there are none, includes is never called. The function should return true, as there is no element that is not included.

If for some reason you want another behaviour, you could do as follows:

function includesAll (needles, haystack) {
    return !needles.length && needles.every(needle => haystack.includes(needle));
}

This way you require that the function can only return true if needles has at least one element.

Upvotes: 2

Damon
Damon

Reputation: 4336

You have a flaw in your logic. In your includesAll function, you are comparing two arrays. As such,

includesAll([], [1]);

should return true.

This is not equivalent to checking

[1].includes([]);

which is checking if the array [1] contains an empty array, which it does not.

In terms of your function, that would be like checking

includesAll([[]], [1]);

which should return false

Upvotes: 1

Related Questions