APixel Visuals
APixel Visuals

Reputation: 89

JavaScript/Node.JS - compact way of using OR operator?

Let's say I have a situation for checking a string. I need to check if it matches a or matches b. Now, of course, I could just do

var firstVar = "a"
var secondVar = "b"
var message = "atest" // note that I might not know what message is. it could be anything. it could be just "test" or just "a"
if ((message === firstVar + "test") || (message === secondVar + "test")) {
   console.log("success!")
}

but is there any way to compact this down? Something relating to having a myVar being an array with values of a and b and then checking if message starts with any value in myVar? If anyone has a tip, that would be much appreciated. Thanks!

Upvotes: 0

Views: 188

Answers (5)

Danziger
Danziger

Reputation: 21191

I would probably use Array.prototype.some on the array of prefixes and then...:

  • If the prefixes are all single characters, just do messsage[0] === prefix, which should be the fastest option (no function calls and no string concatenation, just a simple and fast comparison operator.

    const prefixes = ["a", "b"];
    const message1 = "atest";
    const message2 = "btest";
    const message3 = "ctest";
    
    console.log(prefixes.some(prefix => message1[0] === prefix));
    console.log(prefixes.some(prefix => message2[0] === prefix));
    console.log(prefixes.some(prefix => message3[0] === prefix));

  • If the prefixes can have more than one character (also works for a single character), then I would do message.indexOf(prefix) === 0:

    const prefixes = ["at", "bt"];
    const message1 = "atest";
    const message2 = "btest";
    const message3 = "ctest";
    
    console.log(prefixes.some(prefix => message1.indexOf(prefix) === 0));
    console.log(prefixes.some(prefix => message2.indexOf(prefix) === 0));
    console.log(prefixes.some(prefix => message3.indexOf(prefix) === 0));

You could also build and use a RegExp, which might be faster (depending on the amount and size of the prefixes) if you are going to execute the code multiple times (it will have a penalization the first time you build the RegExp from a string, but then you just reuse that one over and over):

  • If the prefixes are a single character:

    const prefixes = ["a", "b"];
    const message1 = "atest";
    const message2 = "btest";
    const message3 = "ctest";
    
    const regexp = new RegExp(`^[${ prefixes.join('') }]`);
    
    console.log(regexp.test(message1))
    console.log(regexp.test(message2))
    console.log(regexp.test(message3))

  • If the prefixes are multiple characters (also works for a single character):

    const prefixes = ["at", "bt"];
    const message1 = "atest";
    const message2 = "btest";
    const message3 = "ctest";
    
    const regexp = new RegExp(`^(${ prefixes.join('|') })`);
    
    console.log(regexp.test(message1))
    console.log(regexp.test(message2))
    console.log(regexp.test(message3))

If you want to check that message is actually a combination of any of those prefixes plus something else, let's say "test" in your example, then you may want to precompute all the possible options:

  • With an Array (or Set as @Bergi suggested) and Array.prototype.includes or Array.prototype.indexOf

    const prefixes = ["a", "b"];
    const word = "test";
    const options = prefixes.map(prefix => `${ prefix }${ word }`);
    const message1 = "atest";
    const message2 = "btest";
    const message3 = "ctest";
    
    console.log(options.includes(message1));
    console.log(options.includes(message2));
    console.log(options.includes(message3));
    
    console.log(options.indexOf(message1) !== -1);
    console.log(options.indexOf(message2) !== -1);
    console.log(options.indexOf(message3) !== -1);

  • With a RegExp and RegExp.prototype.test or String.prototype.match:

    const prefixes = ["a", "b"];
    const word = "test";
    const regexp = new RegExp(`^(${ prefixes.join("|") })${ word }`);
    const message1 = "atest";
    const message2 = "btest";
    const message3 = "ctest";
    
    console.log(regexp.test(message1));
    console.log(regexp.test(message2));
    console.log(regexp.test(message3));
    
    console.log(!!message1.match(regexp));
    console.log(!!message2.match(regexp));
    console.log(!!message3.match(regexp));

Upvotes: 1

Bergi
Bergi

Reputation: 665546

Using an array with some will be the simplest approach:

var tests = ["a", "b"];
var message = "atest";
if (tests.some(function(t) { return message === t + "test"; })) {
    console.log("success!")
}

If you can use ES6 and need to run this check very often, it might make sense to use

const choices = new Set(["a", "b"].map(t => t + "test"));
…
var message = "atest";
if (choices.has(message)) {
    console.log("success!")
}

Upvotes: 5

Alec Fenichel
Alec Fenichel

Reputation: 1317

ES5:

var vars = ["a", "b"].map(function(v) {
  return v + "test";
});
var message = "atest";
if (vars.indexOf(message) > -1) {
   console.log("success!");
}

ES6:

var vars = ["a", "b"].map(v => v + "test");
var message = "atest";
if (vars.includes(message)) {
   console.log("success!");
}

Upvotes: 1

Dominik
Dominik

Reputation: 6313

Use includes; based on your edit:

const allowed = ['a','b','ccc'];

if( allowed.includes(`${ message }test`) ) {
    console.log("success!")
}

Upvotes: 0

Mike Tung
Mike Tung

Reputation: 4831

Example of using includes and vanilla

ES6 way

const testArray = [1,2,3];

testArray.includes(1); //returns true
testArray.includes(24); //returns false

ES5 way

var testArray = [1,2,3];
testArray.indexOf(1) // returns 1 since its a member.
testArray.indexOf(43) //returns -1 since it's not a member.

Upvotes: 0

Related Questions