Run_Script
Run_Script

Reputation: 2548

Check if an array includes an array in JavaScript

The JavaScript includes function tells you whether 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, since each of these is present in the array arr.

Passing 3 to the function returns false because this is not present in the array.

However, why does arr.includes([1, 2]) also return false, 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]?

Upvotes: 4

Views: 9753

Answers (4)

Midstickgod
Midstickgod

Reputation: 1

To solve the issue of the array.includes() method not detecting 2-d arrays, you could convert the array to a string with the .join method and see if the string includes the 2-d array. For example:

const demo1 = document.getElementById("demo1");
const demo2 = document.getElementById("demo2");
const array = [[1, 2], [3, 4], ["Hi", true]];
const string = array.join(" - ");
demo1.innerHTML = "Array:<BR>" + array;
demo2.innerHTML= "String: <BR>" + string;
<p id="demo1"></p>
<p id="demo2"></p>

Then use the string.includes() method to work out if the string includes the set of characters you want to look for.

The only problem with converting the array to a string is that is can only detect 1 data type which is a string. In full:

    const demo1 = document.getElementById("demo1");
    const demo2 = document.getElementById("demo2");
    const array = [[1, 2], [3, 4], ["Hi", true]];
    const string = array.join(" - ");
    demo1.innerHTML = "Array:<BR>" + array;
    demo1.innerHTML += "<BR><b>Tests:</b><BR>";
    demo1.innerHTML += "Includes [1, 2]: " + array.includes([1,2]) + " Should be true but an array doesn't detect 2-d arrays<BR>";
    demo1.innerHTML += "Includes [2, 3]: " + array.includes([2,3]) + " Should be false but the array shows false not because it doesn't contain the [2, 3] array but because it doesn't understand the square brackets";
    demo2.innerHTML= "String: <BR>" + string;
    demo2.innerHTML += "<BR><b>Tests:</b><BR>";
    demo2.innerHTML += "Includes [1, 2]: " + string.includes("1,2") + "  The answer is true because the string does contain the characters '1,2'<BR>";
    demo2.innerHTML += "Includes [2, 3]: " + string.includes("2,3") + " It is false because the string doesn't includes the character '2,3' and instead contains the characters 2 - 3 because it is the same array joined with ' - '";
<p id="demo1"></p>
<p id="demo2"></p>

Also in the string.includes() function make sure to input a string: Do this: string.includes("Message you want to see whether the string includes or not"); Rather than this: string.includes(Message you want to see whether the string includes or not);

Upvotes: 0

abulka
abulka

Reputation: 1496

If you don't mind using lodash, this algorithm is accurate.

import _ from 'lodash';

export const includesArray = (haystack, needle) => {
    for (let arr of haystack)
        if (_.isEqual(arr, needle)) {
            return true
    }
    return false
}

Upvotes: 1

Yousaf
Yousaf

Reputation: 29282

.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:

  1. 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 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.

Upvotes: 3

Fullstack Guy
Fullstack Guy

Reputation: 16908

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));

Upvotes: 4

Related Questions