admin管理员组

文章数量:1422048

I was wondering if there is a way to check multiple conditions for the same variable or value without repeating that value.

For example, if I had the variable keyCode, and I wanted to check if it was greater than 102, or less than 48, or between 65 and 57, or between 70 and 97, I would have to write this:

var keyCode = // some value;
if(
    keyCode > 102 ||
    keyCode < 48 ||
    (keyCode > 57 && keyCode < 65) ||
    (keycode > 70 && keyCode < 97)
) {
    // do something
}

As you can see, I write keyCode in the if condition 6 times. If the condition were more plex (this one simply rules out all non-hexadecimal characters), then it could be even more repetitive.

I was wondering if there was a way to simplify this. Maybe something like this:

if(
    keyCode > 102 || < 48 || (> 57 && < 65) || (> 70 && < 97)
) {
    // do something
}

in which you could simply omit the variable name and just put many conditionals on a single variable. It's like the opposite of this question, in which the asker was wondering if there was a way to check multiple variables against a single condition.

I'm coding in JS now, but if you know implementations of this in any other language, that might be helpful in the future as well. I thought there would be an easy implementation of this, because I use it so often, but I was surprised to see that I couldn't find any information on any language feature like this at all.

I was wondering if there is a way to check multiple conditions for the same variable or value without repeating that value.

For example, if I had the variable keyCode, and I wanted to check if it was greater than 102, or less than 48, or between 65 and 57, or between 70 and 97, I would have to write this:

var keyCode = // some value;
if(
    keyCode > 102 ||
    keyCode < 48 ||
    (keyCode > 57 && keyCode < 65) ||
    (keycode > 70 && keyCode < 97)
) {
    // do something
}

As you can see, I write keyCode in the if condition 6 times. If the condition were more plex (this one simply rules out all non-hexadecimal characters), then it could be even more repetitive.

I was wondering if there was a way to simplify this. Maybe something like this:

if(
    keyCode > 102 || < 48 || (> 57 && < 65) || (> 70 && < 97)
) {
    // do something
}

in which you could simply omit the variable name and just put many conditionals on a single variable. It's like the opposite of this question, in which the asker was wondering if there was a way to check multiple variables against a single condition.

I'm coding in JS now, but if you know implementations of this in any other language, that might be helpful in the future as well. I thought there would be an easy implementation of this, because I use it so often, but I was surprised to see that I couldn't find any information on any language feature like this at all.

Share Improve this question edited May 23, 2017 at 12:02 CommunityBot 11 silver badge asked Jan 27, 2016 at 18:29 Jonathan LamJonathan Lam 17.4k17 gold badges71 silver badges99 bronze badges 11
  • the purpose of a condition is a parison, right? Well, you are trying to remove one of the paritors it seems to construct a shorthand condition. That isnt a thing. Its good for pseudo code, but for actual implementations within javascript, its a no-go – Fallenreaper Commented Jan 27, 2016 at 18:33
  • @FallenReaper I feel like it should be "a thing." I don't like messy, repetitive code, and I hope there's some shorthand condition or other more elegant solution than what I have to start. Do you have any alternative ideas? – Jonathan Lam Commented Jan 27, 2016 at 18:35
  • pre-populate an array to use as a lookup table for the key code to determine it's acceptability: if(ok[keyCode])..., where array is like [0,0,0,1,1,0,1...] – dandavis Commented Jan 27, 2016 at 18:36
  • @dandavis That would only work in the specific situation I gave above (keycodes with finite possibilities). That won't work in most other solutions. – Jonathan Lam Commented Jan 27, 2016 at 18:37
  • not sure what you mean, there are only so-many keys... you can use different collections: if(arrArrows[keyCode] || arrPauses[keyCode]) – dandavis Commented Jan 27, 2016 at 18:39
 |  Show 6 more ments

5 Answers 5

Reset to default 3

the only way to simplify this I know is to create separate functions with meaningful names, like:

function inRange(value, min, max) {
    return (value > min) && (value < max);
}
function outRange(value, min, max) {
    return (value < min) || (value > max);
}

then your condition will look like this:

if (outRange(keyCode, 48, 102) || inRange(keyCode, 57, 65) || inRange(keyCode, 70, 97) ) {
    ...
}

which is a little bit easier to understand because you see original intent, instead different > < and trying to understand what it actually means

another approach for this could be creation of the object rangeChecker/notInRangeChecker, then create array of different range checkers and create function checkValueAtLeastInOneRange(keyCode, rangesArray)

There is no way to do something like that sintax wise, but you could do something to try to emulate that:

var keyCode = 40

var ranges = [
  [102,Infinity],
  [0,48],
  [57,65],
  [70,97]
]

var allowed = ranges.some(function(values){
    return keyCode > values[0] && keyCode < values[1]
})

if(allowed){
   console.log("allowed")
}else{
  console.log("not allowed")
} 

Some languages, such as Python, support chained parisons, so you can say 42 < x <= y < 84. However, in general, I'm not personally aware of the exact feature you describe. It looks nice, though!

For small domains, like keycodes, you can put the codes of interest in an array and test for set membership:

if keyCode in (range(102,256)+range(0,49)+range(58,65)+range(71,97)):
    # do something

(The + takes the union of the ranges by putting them all in one list.)

No, you can't remove the variable as every condition gets evaluated by it's own. But to reuse certain checks i suggest you to extract them to an object of functions (and require it from another file):

var keyTester = {
    isA: function (keyCode) {
        return keyCode > 102;
    },
    isB: function (keyCode) {
        return keyCode < 48;
    },
    isC: function  (keyCode) {
        keyCode > 57 && keyCode < 65;
    }
};

if (keyTester.isA(keyCode) || keyTester.isB(keyCode) || keyTester.isC(keyCode) ... )

One other thought - use a short alias, e.g., _, for your variable:

if(
    (_=keyCode) > 102 || _ < 48 || (_ > 57 && _ < 65) || ( _ > 70 && _ < 97)
) {
    // do something
}

Make sure you don't use _ for anything that can't be discarded at an if statement :) . The (_=keyCode) stashes the value with very few extra keystrokes, and then _ can be used throughout. && and || evaluate left-to-right (reference), so _ should be available throughout the rest of the condition.

I did a quick test: in Google Chrome,

var x=42; 
if((_=x)<99 && _>30) { console.log(x);}

works (prints 42 as expected).

本文标签: javascriptIf statement multiple conditionals on one value without repeating valueStack Overflow