15

I need to check if an array includes two values and only them.

This is my ugly solution for now:

if (myArray.includes('foo') && myArray.includes('bar') && myArray.length === 2) { // Do something } 

Update:

I may have to check three or more values as well. Any elegant solution? By the way, I'm using Lodash in this project.

0

3 Answers 3

12

I may have to check three or more values as well.

You could present your elements as an array, so if you've more than two items to check, the condition will still short and the same, using .every() method like:

myArray.every(elem => [1,2].indexOf(elem) > -1) 

var myArray = [2, 1]; var myItems = [1, 2]; if (myArray.length === myItems.length && myArray.every(elem => myItems.indexOf(elem) > -1)) { console.log('PASS'); }

UPDATE:

Since you're using lodash, you could simply use _.difference() like:

if (_.size(myArray) === _.size(myItems) && _.difference(myArray, myItems).length === 0) { // Do something } 
Sign up to request clarification or add additional context in comments.

5 Comments

Check my lodash suggestion @isar
Thank you... I did but it didn't work as expected until I did this: (myArray.length === myItems.length && _.difference(myArray, myItems).length === 0).
Yes and if you want to use just lodash check my update using _.size
Why use a lodash function when vanilla JS is the better and clearer option? Does it offer any advantages?
Why you think it's the better and clearer?
10

That is the proper way which you have used. But to improve the comparison you can put myArray.length === 2 at the begining as if the length is not 2 it will fail immediately:

if (myArray.length === 2 && myArray.includes('foo') && myArray.includes('bar')) { // do something }

If your want to compare more values then you can check that with the help of a custom function:

function checkIncluded(myArray, checkingArray){ if(myArray.length !== checkingArray.length){ return false; } var match = true; for(var i=0; i<checkingArray.length; i++){ if(!myArray.includes(checkingArray[i])){ match = false; break; } } return match; } var neededItems = ['foo', 'bar', 'pat', 'jack']; var myArray = ['jack', 'bar', 'foo', 'pat'] var included = checkIncluded(myArray, neededItems); if (included) { console.log('All items matched'); } else { console.log('All items do not matched'); } neededItems = ['bar', 'pat', 'jack']; myArray = ['jack', 'bar', 'foo', 'pat'] included = checkIncluded(myArray, neededItems); if (included) { console.log('All items matched'); } else { console.log('All items do not matched'); }

3 Comments

What does the "&&" at the end do?
@ramden nothing
Returns true for ['foo', 'foo'] and ['foo', 'bar'] (but OP is not clear about it).
2

A different and pretty simple approach:

const checkExact = (arr, v1, v2) => `${v1}${v2}` === String(arr.join("")); const arr1 = [1, 2, 3]; const arr2 = [15, 23]; const arr3 = ["foo", "bar"]; const arr4 = ["foo", "bar", "foobar"]; console.log( checkExact(arr1, 1, 2), // false checkExact(arr2, 15, 23), // true checkExact(arr3, "foo", "bar"), // true checkExact(arr4, "foo", "bar") // false ); // more generic const checkExactX = (arr, ...values) => values.reduce( (p, n) => `${p}${n}`, "" ) === String(arr.join("")); const arr5 = ["foo", "bar", "foobar", "barfoo"]; console.log( checkExactX(arr1, 1, 2), // false checkExactX(arr2, 15, 23), // true checkExactX(arr3, "foo", "bar"), // true checkExactX(arr4, "foo", "bar", "foobar"), // true checkExactX(arr4, "foobarfoobar"), // true checkExactX(arr5, "foo", "bar", "foobar") // false );

1 Comment

The problem here is that the values must appear in the exact order for the tests to pass. So you can have an exact match but the order of the parameters are reversed and this function will fail.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.