'Check if an array includes an array in javascript
The javascript includes
function can be used to find if an element is present in an array. Take the following example:
var arr = ['hello', 2, 4, [1, 2]];
console.log( arr.includes('hello') );
console.log( arr.includes(2) );
console.log( arr.includes(3) );
console.log( arr.includes([1, 2]) );
Passing 'hello'
or 2
to the function returns true
, as both are present in the array arr
.
Passing 3
to the function returns false
because it is not present in the array.
However, why does arr.includes([1, 2])
return false
as well, even though this is equal to the last element in the array? And if this method does not work, how else can I find whether my array includes the item [1, 2]
?
Solution 1:[1]
The Array#includes
checks by shallow comparison, so in your case the string and numbers are primitives there is only ever a single instance of them so you get true
from Array#includes
.
But when you check for array, you are passing a new array instance which is not the same instance in the array you are checking so shallow comparison fails.
To check for an array is included in another array first check if it is an array then do a deep comparison between the arrays.
- Note that below snippet only works for an array of primitives:
var arr = ['hello', 2, 4, [1, 2]];
const includesArray = (data, arr) => {
return data.some(e => Array.isArray(e) && e.every((o, i) => Object.is(arr[i], o)));
}
console.log(includesArray(arr, [1, 2]));
But if you keep the reference to the array [1, 2]
and search with the reference the Array#includes
works as in this case the shallow comparison works perfectly (obeying same value zero algorithm):
const child = [1, 2];
const arr = ['hello', 2, 4, child];
console.log(arr.includes(child));
Solution 2:[2]
.includes()
method uses sameValueZero equality
algorithm to determine whether an element is present in an array or not.
When the two values being compared are not numbers, sameValueZero
algorithm uses SameValueNonNumber
algorithm. This algorithm consists of 8 steps and the last step is relevant to your code , i.e. when comparison is made between two objects. This step is:
- Return true if x and y are the same Object value. Otherwise, return false.
So in case of objects, SameValueZero
algorithm returns true only if the two objects are the same.
In your code, since the array [1, 2]
inside arr
array is identically different to [1, 2]
that you passed to .includes()
method, .includes()
method can't find the array inside arr
and as a result returns false
.
Solution 3:[3]
If you don't mind using lodash, this algorithm is accurate - unlike the accepted answer.
import _ from 'lodash';
export const includesArray = (haystack, needle) => {
for (let arr of haystack)
if (_.isEqual(arr, needle)) {
return true
}
return false
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | abulka |