7

I have

['a', 'b', 'c']

I want to know if this array is contained in this array:

['a', 'b', 'c', 'd']

I know I can do 2 for loops and check item per item, but is there a oneliner for it?

8
  • Do you mean you want to know if the values of array 1 are in array 2? Or if th whole array (including []) is in it? Commented Aug 5, 2015 at 14:33
  • Maybe see stackoverflow.com/questions/1723168/… Commented Aug 5, 2015 at 14:33
  • @Alan I mean the values Commented Aug 5, 2015 at 14:34
  • stackoverflow.com/questions/8628059/… Commented Aug 5, 2015 at 14:36
  • 2
    If the array elements are simple strings as shown in your example, you can do contains = (y.sort().join('').indexOf(x.sort().join('')) !== -1); - where x is the smaller array (needed) and y is the larger one (haystack). Commented Aug 5, 2015 at 14:37

2 Answers 2

14

You can do this using Array.prototype.some. This will run the provided function against all the items in an array, and return true if the function returns true for any of them. The following will return true if any items from array are not contained in otherArray, which you can use to determine if one array is fully contained in the other:

return !array.some(function(item) {
   return otherArray.indexOf(item) === -1;
});

However, this is not the most elegant solution. The logic can be summed up as:

not any items from array not in other array

Which has far too many negatives. We can instead use Array.prototype.every, which is very similar except it returns true only if all items in an array return true for the provided function. The below is equivalent to what we had before:

return array.every(function(item) {
   return otherArray.indexOf(item) !== -1;
});

Except that can be summed up as:

all items in array in other array

Finally, we can implement this as an additional prototype function. Note that the second parameter for every is optional, and sets what this refers to in the function when provided. If we did not pass it in, we would not be able to refer to the this from the outside scope.

Array.prototype.contains = function(array) {
    return array.every(function(item) {
        return this.indexOf(item) !== -1;
    }, this);
}

This can now be used as a one liner in our code:

['a', 'b', 'c'].contains(['a', 'b']) // returns true

If you are able to use ECMAScipt 6, you can use arrow functions to make this a true one-liner.

return array.every(item => otherArray.indexOf(item) !== -1);
Sign up to request clarification or add additional context in comments.

1 Comment

Array.prototype.some and Array.prototype.every are part of ECMAScript 5, which is supported in most modern browsers, including mobile browsers. Worth noting it's not supported in IE8 or earlier. caniuse.com/#feat=es5
8

ES6 one-lined answer

containedArray.every(element => mainArray.includes(element))

...an improved answer on top of the ES6 suggestion of @James Brierley: by using every(...) (which returns true if all the elements pass the test we've provided - false otherwise) alongside includes, which IMO is more human-readable - and less error prone - than checking for a index !== -1.

var mainArray = [1, 30, 39, 29, 10, 13];

var containedArray = [1, 30, 39, 29]

console.log(containedArray.every(element => mainArray.includes(element)));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.