173

I want a function that returns true if and only if a given array includes all the elements of a given "target" array. As follows.

const target = [ 1, 2, 3,    ];
const array1 = [ 1, 2, 3,    ]; // true
const array2 = [ 1, 2, 3, 4, ]; // true
const array3 = [ 1, 2,       ]; // false

How can I accomplish the above result?

0

11 Answers 11

335

You can combine the .every() and .includes() methods:

let array1 = [1,2,3],
    array2 = [1,2,3,4],
    array3 = [1,2];

let checker = (arr, target) => target.every(v => arr.includes(v));

console.log(checker(array2, array1));  // true
console.log(checker(array3, array1));  // false

Sign up to request clarification or add additional context in comments.

Comments

54

The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value. Stands to reason that if you call every() on the original array and supply to it a function that checks if every element in the original array is contained in another array, you will get your answer. As such:

const ar1 = ['a', 'b'];
const ar2 = ['c', 'd', 'a', 'z', 'g', 'b'];

if(ar1.every(r => ar2.includes(r))){
  console.log('Found all of', ar1, 'in', ar2);
}else{
  console.log('Did not find all of', ar1, 'in', ar2);
}

Comments

32

You can try with Array.prototype.every():

The every() method tests whether all elements in the array pass the test implemented by the provided function.

and Array.prototype.includes():

The includes() method determines whether an array includes a certain element, returning true or false as appropriate.

var mainArr = [1,2,3];
function isTrue(arr, arr2){
  return arr.every(i => arr2.includes(i));
}
console.log(isTrue(mainArr, [1,2,3]));
console.log(isTrue(mainArr, [1,2,3,4]));
console.log(isTrue(mainArr, [1,2]));

Comments

1

If you are using ES5, then you can simply do this.

targetArray =[1,2,3]; 
array1 = [1,2,3]; //return true
array2 = [1,2,3,4]; //return true
array3 = [1,2] //return false

console.log(targetArray.every(function(val) { return array1.indexOf(val) >= 0; })); //true
 console.log(targetArray.every(function(val) { return array2.indexOf(val) >= 0; })); // true
 console.log(targetArray.every(function(val) { return array3.indexOf(val) >= 0; }));// false

Comments

1

I used Purely Javascript.

function checkElementsinArray(fixedArray,inputArray)
{
    var fixedArraylen = fixedArray.length;
    var inputArraylen = inputArray.length;
    if(fixedArraylen<=inputArraylen)
    {
        for(var i=0;i<fixedArraylen;i++)
        {
            if(!(inputArray.indexOf(fixedArray[i])>=0))
            {
                return false;
            }
        }
    }
    else
    {
        return false;
    }
    return true;
}

console.log(checkElementsinArray([1,2,3], [1,2,3]));
console.log(checkElementsinArray([1,2,3], [1,2,3,4]));
console.log(checkElementsinArray([1,2,3], [1,2]));

Comments

1

reduce can be used here as well (but it has O = (N * M) difficulty):

const result = target.reduce((acc, el) => {
    return acc && array.includes(el)
}, true);

To solve this in more efficient way(O = N + M):

const myMap = new Map();

array.forEach(element => myMap.set(element);

const result = target.reduce((acc, el) => {
   return acc && myMap.has(el)
}, true);

Comments

1

TC39 is specifying a number of additional Set methods to be added to ECMAScript, currently scheduled for ECMAScript 2025.

The isSubsetOf() and isSupersetOf() methods are already supported by most major browsers, and should give you better time complexity than other solutions.

With that you could do:

const target = [1, 2, 3];    
const array1 = [1, 2, 3];
const array2 = [1, 2, 3, 4];
const array3 = [1, 2];

console.log(new Set(target).isSubsetOf(new Set(array1))); // true
console.log(new Set(target).isSubsetOf(new Set(array2))); // true
console.log(new Set(target).isSubsetOf(new Set(array3))); // false

// OR

console.log(new Set(array1).isSupersetOf(new Set(target))); // true
console.log(new Set(array2).isSupersetOf(new Set(target))); // true
console.log(new Set(array3).isSupersetOf(new Set(target))); // false

Of course, in an actual implementation you'd want to eliminate the overhead of creating the target set multiple times.

If the current browser support is insufficient for your needs, you can always rely on a shim/polyfill.

Comments

0

If you're checking if array x contains everything in array y, including requiring multiple occurrences of elements in y to appear multiple times in x:

function arrayContains(x,y) {
  // returns true if array x contains all elements in array y
  return !x.reduce((y,e,t)=>
    (t=y.indexOf(e),t>=0&&y.splice(t,1),y),[...y]).length
}

console.log(arrayContains([1,2,3],   [1,5]))    // false - no 5 present
console.log(arrayContains([1,2,3],   [1,2]))    // true
console.log(arrayContains([1,2,3],   [1,2,2]))  // false - not enough 2s
console.log(arrayContains([2,1,2,3], [2,2,1]))  // true

Comments

0

you can compute the difference of the two arrays, if the target becomes empty, that means that all the elements where found ;)

const target = [ 1, 2, 3,    ];
const array1 = [ 1, 2, 3,    ]; // true
const array2 = [ 1, 2, 3, 4, ]; // true
const array3 = [ 1, 2,       ]; // false

const containsAll = (target, array) => {
  const difference = target.filter(x => !array.includes(x))
  return difference.length === 0
};

console.assert(containsAll(target, array1), "should be true");
console.assert(containsAll(target, array2), "should be true");
console.assert(containsAll(target, array3) === false, "should be false");

Comments

0

const target = [1, 2, 3];
const array1 = [1, 2, 3];
const array2 = [1, 2, 3, 4, ]; // true
const array3 = [1, 2, ];

function check(targetarr, arr) {
  return targetarr.map((e) => {
    return (arr.includes(e)) ? true : false;
  }).every((e) => e === true);
}
console.log(check(target, array1));
console.log(check(target, array2));
console.log(check(target, array3));

Comments

0

In term of code this approach may be efficient. If performance is the priority and in case of large Arrays, you will perhaps consider sorting the arrays first, then use a more efficient way to do this.

Sorry, I just discovered this post and didn't read all the answers, so forgive me if this method is already mentioned.

const target = [ 1, 2, 3,    ];
const array1 = [ 1, 2, 3,    ]; // true
const array2 = [ 1, 2, 3, 4, ]; // true
const array3 = [ 1, 2,       ]; // false
const array4 = [20,1,6,2,10,3]; // true

function containsAllElmnts(array, target) {
  return target.every(element => array.includes(element));
}

console.log("reference (target) => " + target);

console.log(array1 + " => " + (containsAllElmnts(array1, target)));
console.log(array2 + " => " + (containsAllElmnts(array2, target)));
console.log(array3 + " => " + (containsAllElmnts(array3, target)));
console.log(array4 + " => " + (containsAllElmnts(array4, target)));

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.