How to check whether multiple values exist within an Javascript array

JavascriptJqueryArrays

Javascript Problem Overview


So, I'm using Jquery and have two arrays both with multiple values and I want to check whether all the values in the first array exist in the second.

For instance, example 1...

> Array A contains the following values > > 34, 78, 89 > > Array B contains the following values > > 78, 67, 34, 99, 56, 89 > > This would return true

...example 2:

> Array A contains the following values > > 34, 78, 89 > > Array B contains the following values > > 78, 67, 99, 56, 89 > > This would return false

...example 3:

> Array A contains the following values > > 34, 78, 89 > > Array B contains the following values > > 78, 89 > > This would return false

So far I have tried to solve this by:

  1. Extending Jquery with a custom 'compare' method to compare the two arrays. Problem is this only returns true when the arrays are identical and as you can see from example 1 I want it to return true even if they aren't identical but at least contain the value
  2. using Jquerys .inArray function, but this only checks for one value in an array, not multiple.

Any light that anyone could throw on this would be great.

Javascript Solutions


Solution 1 - Javascript

Native JavaScript solution

var success = array_a.every(function(val) {
    return array_b.indexOf(val) !== -1;
});

You'll need compatibility patches for every and indexOf if you're supporting older browsers, including IE8.


Full jQuery solution

var success = $.grep(array_a, function(v,i) {
    return $.inArray(v, array_b) !== -1;
}).length === array_a.length;

Uses $.grep with $.inArray.


ES2015 Solution

The native solution above can be shortened using ES2015's arrow function syntax and its .includes() method:

let success = array_a.every((val) => array_b.includes(val))

Solution 2 - Javascript

function containsAll(needles, haystack){ 
  for(var i = 0; i < needles.length; i++){
     if($.inArray(needles[i], haystack) == -1) return false;
  }
  return true;
}

containsAll([34, 78, 89], [78, 67, 34, 99, 56, 89]); // true
containsAll([34, 78, 89], [78, 67, 99, 56, 89]); // false
containsAll([34, 78, 89], [78, 89]); // false

Solution 3 - Javascript

A one-liner to test that all of the elements in arr1 exist in arr2...

With es6:

var containsAll = arr1.every(i => arr2.includes(i));

Without es6:

var containsAll = arr1.every(function (i) { return arr2.includes(i); });

Solution 4 - Javascript

I noticed that the question is about solving this with jQuery, but if anyone else who is not limited to jQuery comes around then there is a simple solution using underscore js.

Using underscore js you can do:

_.intersection(ArrayA, ArrayB).length === ArrayA.length;

From the docs:

> intersection_.intersection(*arrays) Computes the list of values that are the intersection of all the arrays. Each value in the result is present in each of the arrays.

> _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2]

Ergo, if one of the items in ArrayA was missing in ArrayB, then the intersection would be shorter than ArrayA.

Solution 5 - Javascript

You could take a Set and check all items agains it.

const containsAll = (needles, haystack) => needles.every(Set.prototype.has, new Set(haystack));

console.log(containsAll([105, 112, 103], [106, 105, 103, 112]));

Solution 6 - Javascript

Just for the fun of it, i've implemented something with Array.prototype.reduce() :

let areKeysPresent = function (sourceArray, referenceArray) {
    return sourceArray.reduce((acc, current) => acc & referenceArray.includes(current), true)
}

Solution 7 - Javascript

You could also add a containsAll to Array prototype like this:

Array.prototype.containsAll = function()
{
	return Array.from(arguments).every(i => this.includes(i));
}

Examples:

["apple", "banana", "strawberry"].containsAll("apple", "banana"); // true

["apple", "banana", "strawberry"].containsAll("apple", "kiwi"); // false

Solution 8 - Javascript

You can use this simple function (renamed variables as per above answer for easy reading):

function contains(haystack, needles) {

    return needles.map(function (needle) { 
        return haystack.indexOf(needle);
    }).indexOf(-1) == -1;
}

Solution 9 - Javascript

Try this.

var arr1 = [34, 78, 89];
var arr2 = [78, 67, 34, 99, 56, 89];

var containsVal = true;
$.each(arr1, function(i, val){
   if(!$.inArray(val, arr2) != -1){
       retVal = false;
       return false;
   }
});

if(containsVal){
    //arr2 contains all the values from arr1 
}

Solution 10 - Javascript

If you need a little bit more visibility on which items are in the array you can use this one :

var tools = {
        elem : {},
        arrayContains : function(needles, arrhaystack) {
           if (this.typeOf(needles) === 'array') {
                needle.reduce(function(result,item,$i,array){ // You can use any other way right there.
                    var present = (arrhaystack.indexOf(item) > -1);
                    Object.defineProperty(tools.elem, item, {
                        value : present,
                        writable : true
                    });
                },{})
                return this.elem;
            }
        },        
        typeOf : function(obj) {
            return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
        }
    }

Use it with simply var check = tools.arrayContains([10,'foo'], [1,'foo','bar'])

Then you get the result like

10 : false
foo : true

Then if you need to get only one result if one of them is true you can :

arr = Object.values(check);
(arr.indexOf('true')) ? instru1 : instru2 ;

I don't think that's the better way but it's working & easily adaptable. Considering this example I advise you to make an Object.create(tools) before use it in your way.

Solution 11 - Javascript

Using array functions: [].filter and [].includes

Something like this:

[34, 78, 89].filter((v) => {
    return [78, 67, 34, 99, 56, 89].includes(v);
});

This will return an array of the matches items

Then we can compare it with needles array

As a function it will be:

const contains = (haystack, needles) => {
    return haystack.filter((v) => {
        return needles.includes(v);
    }).length === needles.length;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBetjaminView Question on Stackoverflow
Solution 1 - Javascriptuser1106925View Answer on Stackoverflow
Solution 2 - JavascriptdriangleView Answer on Stackoverflow
Solution 3 - Javascriptpulse0neView Answer on Stackoverflow
Solution 4 - JavascriptdatacarlView Answer on Stackoverflow
Solution 5 - JavascriptNina ScholzView Answer on Stackoverflow
Solution 6 - Javascriptludovic DView Answer on Stackoverflow
Solution 7 - JavascriptMirosView Answer on Stackoverflow
Solution 8 - JavascriptcalebView Answer on Stackoverflow
Solution 9 - JavascriptShankarSangoliView Answer on Stackoverflow
Solution 10 - JavascriptDaryl CluzelView Answer on Stackoverflow
Solution 11 - Javascriptuser7153178View Answer on Stackoverflow