Check variable equality against a list of values

Javascript

Javascript Problem Overview


I'm checking a variable, say foo, for equality to a number of values. For example,

if( foo == 1 || foo == 3 || foo == 12 ) {
    // ...
}

The point is that it is rather much code for such a trivial task. I came up with the following:

if( foo in {1: 1, 3: 1, 12: 1} ) {
    // ...
}

but also this does not completely appeal to me, because I have to give redundant values to the items in the object.

Does anyone know a decent way of doing an equality check against multiple values?

Javascript Solutions


Solution 1 - Javascript

You could use an array and indexOf:

if ([1,3,12].indexOf(foo) > -1)

Solution 2 - Javascript

In ECMA2016 you can use the includes method. It's the cleanest way I've seen. (Supported by all major browsers)

if([1,3,12].includes(foo)) {
    // ...
}

Solution 3 - Javascript

Using the answers provided, I ended up with the following:

Object.prototype.in = function() {
    for(var i=0; i<arguments.length; i++)
       if(arguments[i] == this) return true;
    return false;
}

It can be called like:

if(foo.in(1, 3, 12)) {
    // ...
}

Edit: I came across this 'trick' lately which is useful if the values are strings and do not contain special characters. For special characters is becomes ugly due to escaping and is also more error-prone due to that.

/foo|bar|something/.test(str);

To be more precise, this will check the exact string, but then again is more complicated for a simple equality test:

/^(foo|bar|something)$/.test(str);

Solution 4 - Javascript

Now you may have a better solution to resolve this scenario, but other way which i preferred.

const arr = [1,3,12]
if( arr.includes(foo)) { // it will return true if you `foo` is one of array values else false
  // code here    
}

I preferred above solution over the indexOf check where you need to check index as well.

includes docs

if ( arr.indexOf( foo ) !== -1 ) { }

Solution 5 - Javascript

This is easily extendable and readable:

switch (foo) {
    case 1:
    case 3:
    case 12:
        // ...
        break

    case 4:
    case 5:
    case 6:
        // something else
        break
}

But not necessarily easier :)

Solution 6 - Javascript

You can write if(foo in L(10,20,30)) if you define L to be

var L = function()
{
	var obj = {};
	for(var i=0; i<arguments.length; i++)
		obj[arguments[i]] = null;
		
	return obj;
};

Solution 7 - Javascript

var a = [1,2,3];

if ( a.indexOf( 1 ) !== -1 ) { }

Note that indexOf is not in the core ECMAScript. You'll need to have a snippet for IE and possibly other browsers that dont support Array.prototype.indexOf.

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(searchElement /*, fromIndex */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (len === 0)
      return -1;

    var n = 0;
    if (arguments.length > 0)
    {
      n = Number(arguments[1]);
      if (n !== n)
        n = 0;
      else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
    }

    if (n >= len)
      return -1;

    var k = n >= 0
          ? n
          : Math.max(len - Math.abs(n), 0);

    for (; k < len; k++)
    {
      if (k in t && t[k] === searchElement)
        return k;
    }
    return -1;
  };
}

Solution 8 - Javascript

Also, since the values against which you're checking the result are all unique you can use the Set.prototype.has() as well.

var valid = [1, 3, 12];
var goodFoo = 3;
var badFoo = 55;

// Test
console.log( new Set(valid).has(goodFoo) );
console.log( new Set(valid).has(badFoo) );

Solution 9 - Javascript

I liked the accepted answer, but thought it would be neat to enable it to take arrays as well, so I expanded it to this:

Object.prototype.isin = function() {
    for(var i = arguments.length; i--;) {
        var a = arguments[i];
        if(a.constructor === Array) {
            for(var j = a.length; j--;)
                if(a[j] == this) return true;
        }
        else if(a == this) return true;
    }
    return false;
}

var lucky = 7,
    more = [7, 11, 42];
lucky.isin(2, 3, 5, 8, more) //true

You can remove type coercion by changing == to ===.

Solution 10 - Javascript

If you have access to Underscore, you can use the following:

if (_.contains([1, 3, 12], foo)) {
  // ...
}

contains used to work in Lodash as well (prior to V4), now you have to use includes

if (_.includes([1, 3, 12], foo)) {
  handleYellowFruit();
}

Solution 11 - Javascript

For a larger list of values that you compare with often, it is likely more optimal to first construct a Set and use Set#has for a constant time check rather than Array#includes which runs in linear time.

const values = new Set([1, 2, 12]);
if(values.has(foo)){
   // do something
}

Solution 12 - Javascript

I simply used jQuery inArray function and an array of values to accomplish this:

myArr = ["A", "B", "C", "C-"];

var test = $.inArray("C", myArr)  
// returns index of 2 returns -1 if not in array

if(test >= 0) // true

Solution 13 - Javascript

This is a little helper arrow function:

const letters = ['A', 'B', 'C', 'D'];

function checkInList(arr, val) {
  return arr.some(arrVal => val === arrVal);
}

checkInList(letters, 'E');   // false
checkInList(letters, 'A');   // true

More info here...

Solution 14 - Javascript

Using the ES6 syntax you can do:

Object.prototype.in = function (...args) {
  return args.includes(this.valueOf());
}

which incidentally also checks for deep equality. The valueOf() method is needed as this is an object.

Solution 15 - Javascript

For posterity you might want to use regular expressions as an alternative. Pretty good browser support as well (ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#Browser_compatibility)

Try this

if (foo.toString().match(/^(1|3|12)$/)) {
    document.write('Regex me IN<br>');
} else {
    document.write('Regex me OUT<br>');
}

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
QuestionpimvdbView Question on Stackoverflow
Solution 1 - JavascriptGumboView Answer on Stackoverflow
Solution 2 - JavascriptAlisterView Answer on Stackoverflow
Solution 3 - JavascriptpimvdbView Answer on Stackoverflow
Solution 4 - JavascriptJaved ShaikhView Answer on Stackoverflow
Solution 5 - JavascriptorlpView Answer on Stackoverflow
Solution 6 - JavascriptElian EbbingView Answer on Stackoverflow
Solution 7 - Javascriptmeder omuralievView Answer on Stackoverflow
Solution 8 - JavascriptIvan SivakView Answer on Stackoverflow
Solution 9 - JavascriptGreg PerhamView Answer on Stackoverflow
Solution 10 - JavascriptDavid SalamonView Answer on Stackoverflow
Solution 11 - JavascriptUnmitigatedView Answer on Stackoverflow
Solution 12 - JavascriptScottyGView Answer on Stackoverflow
Solution 13 - JavascriptnorthernwindView Answer on Stackoverflow
Solution 14 - Javascriptmelv doucView Answer on Stackoverflow
Solution 15 - JavascriptmartisjView Answer on Stackoverflow