Betjamin
Betjamin

Reputation: 805

How to check whether multiple values exist within an Javascript array

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.

Upvotes: 67

Views: 186348

Answers (11)

Miros
Miros

Reputation: 567

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

Upvotes: 2

ludovic D
ludovic D

Reputation: 31

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

Upvotes: 2

user7153178
user7153178

Reputation:

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

Upvotes: 0

driangle
driangle

Reputation: 11779

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

Upvotes: 61

Nina Scholz
Nina Scholz

Reputation: 386522

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

Upvotes: 5

Daryl Cluzel
Daryl Cluzel

Reputation: 1

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.

Upvotes: 0

pulse0ne
pulse0ne

Reputation: 1102

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

Upvotes: 56

user1106925
user1106925

Reputation:

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

Upvotes: 117

datacarl
datacarl

Reputation: 2771

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.

Upvotes: 17

caleb
caleb

Reputation: 1637

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

Upvotes: 0

ShankarSangoli
ShankarSangoli

Reputation: 69905

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 
}

Upvotes: 0

Related Questions