Is there JS shorthand for conditional "not equal to a and not equal to b" and such?
Asked Answered
S

7

6

I was just wondering if there is some JS shorthand for something like this:

if (x != 1 && x != 2) do stuff;

Does such a beast exist? Instead, I want to say something like this:

if (x != 1:2) do stuff;

Sumikosumma answered 14/12, 2012 at 2:53 Comment(6)
On larger ranges it would make sense to do (x < 1 || x > 2), but other than that can't think of alternatives. That's assuming they're integers and you don't have to say take 1.5 into account.Regrate
You can do some hacky stuff with the in operator, but no there isn't really something like what you describe. lhs in rhs will return whether lhs is a property of rhsShiest
if you're looking to include/exclude from the contents of a list, use Array.indexOfManassas
Wow, folks really ran with this. Well, it was just a theory-and-technique type of question. I really like to see the musings and concepts posted here. It provides more insight. The official answer is NO, that syntax functionality does not exist in standard JavaScript. Also, I don't think it exists in jQuery, but I'm not sure. It may exist in another JS library.Sumikosumma
A switch statement seems to be the most appropriate option, which is what I was going to implement anyway.Sumikosumma
However it would be nice to say stuff like if (x == 1 OR 2, || x > 5 AND < 7, && y != 3 AND/OR 6) dostuff; However, it is much harder to misinterpret (for the programmer AND for the parser/compiler) when you keep it broken down to if ((x == 1 || x == 2) || (x > 5 && x < 7) && (y != 3 || y != 6)) (not sure if i copied that properly)Sumikosumma
M
2

No that doesn't exist, and that is good! Only in less precise natural language does such a thing exist, which can lead to confusion.

Megaton answered 14/12, 2012 at 3:2 Comment(3)
Regular expressions support themPoteen
@Poteen i dont think so, but dont mix that up with "expression in list"Megaton
I understand the concept, and you understand my question well. Thanks.Sumikosumma
M
5

No, there is no such shorthand.

You can use a switch if you don't want to repeat the variable:

switch (x) {
  case 1:
  case 2: break;
  default: do stuff;
}

Another alternative would be to look for the value in an array:

if ([1, 2].indexOf(x) == -1) do stuff;

However, the Array.indexOf doesn't exist in all browsers, so you may need a fallback which you can for example find on the Mozilla Array.indexOf documentation page.

Metaplasia answered 14/12, 2012 at 3:5 Comment(6)
Shorter would be if(!!~[1,2].indexOf(x))Trichotomy
@helly0d: Yes, that is perfect; it's both slow and unreadable. ;)Metaplasia
Just what he is looking for :). Never try to shorthand anything if it's just for the sake of writing a few characters less in a code. There are a lot of hacks but most of them are costly.Trichotomy
@Trichotomy Why bother with the !!? It'll already evaluate to something that works correctly for an if statementOvertrump
@Overtrump Besides the fact that it was posted as a joke, the !! was intended for other uses than if statement and it forces the conversion to true or false for these other cases.Trichotomy
@Trichotomy Haha couldn't tell if you were joking before Guffa's comment :) But yeah, I knew what that does, I just thought it could be omitted because it's not being stored or used anywhere else. Anyways, it doesn't matter, as it was a jokeOvertrump
M
2

No that doesn't exist, and that is good! Only in less precise natural language does such a thing exist, which can lead to confusion.

Megaton answered 14/12, 2012 at 3:2 Comment(3)
Regular expressions support themPoteen
@Poteen i dont think so, but dont mix that up with "expression in list"Megaton
I understand the concept, and you understand my question well. Thanks.Sumikosumma
U
1

There are two ways I can think of.

Case 1:

if ([1, 2].indexOf(x) < 0) // do stuff

Case 2:

I wouldn't recommend this way:

if (!(x in {1:0, 2:0})) // do stuff

Stepwise:

  1. We create an object with the numbers to compare against as keys: {1:0, 2:0}
  2. We use the in operator to check whether the value of x is a key of the object.
  3. We negate the resultant boolean using ! because we want to check for inequality.

I suggest you look at CoffeeScript instead. It has chained comparisons which will allow you to do something like this:

if (1 <= x <= 2) // do stuff

It's not the same as your condition, but you might find it interesting.

Unoccupied answered 14/12, 2012 at 3:21 Comment(3)
Instead of 0's for the object's values (Case 2), why not empty strings? Probably wouldn't make that much of a difference, but less memory/space used. Also, it should be noted that using Case 2, it performs a comparison like ==, so === is not possibleOvertrump
And I guess it's just me, but I would definitely recommend Case 2. It may not be as readable, but it would be a much easier lookup than indexOf (at least noticeable for larger amounts of items to match against), and is supported in all browsers.Overtrump
Awesome to see this stuff. Unfortunately, all of it is clunky. The answer is "nope! you have to use this:if (variable-comparator-value and/or variable-comparator-value) dostuff (Pseudocode)Sumikosumma
F
1
var a = 4;
if ([1,2,3,5,7,8,9,0,10,15,100].indexOf(a) == -1) console.log(a);

Will log 4 to console because 4 is not present on the list.

Furnace answered 14/12, 2012 at 3:23 Comment(3)
Note though that the Array.indexOf doesn't exist in all browsers, for example IE8 and earlier.Metaplasia
Just add Array.prototype.indexOf = function(obj, start) { for (var i = (start || 0), j = this.length; i < j; i++) { if (this[i] === obj) { return i; } } return -1; } And then you have it.Papen
At least check if there already is an implementation before replacing it with one that is worse...Metaplasia
E
1

x!=1 && x!=2 is shorthand for the browser- if the first part is false it quits right away. No code you can wrap it in that evaluates both expressions could be nearly as efficient.

Elitism answered 14/12, 2012 at 5:54 Comment(0)
B
0

There would be nothing wrong with writing your own function to add a method to a given object. There are a variety of ways to do that, by extending prototypes or using a namespace. Example syntax might be:

if (!x.equals('1||2')) { /* do your stuff */ }
// the custom method '.equals' would extend a STRING, and return true or false

Another example:

if (π.is(x,['1||2'])) { /* do your stuff */ }
// custom object "π" has a method "is" which checks whether x is 1 or 2, and returns true or false

There are so many ways to do this. Some are frowned upon for very good reasons (extending core object prototypes, for example, is not always ideal as it could impact other libraries and freak people out), and of course there is always the risk of over-engineering. Tread carefully.

Minor note: I intentionally put the logical operator '||', with the idea that the underlying function might be flexible and take other operators, such as '&&' or '!' etc.

Burkitt answered 14/12, 2012 at 3:20 Comment(5)
The expression 1||2 will always express 1. You're losing information.Unoccupied
@AaditMShah edited. The comment tags got stripped for some reason on post.Burkitt
Is there any reason you wouldn't rather use [1, 2].indexOf(x) < 0?Unoccupied
@AaditMShah Nope. Your answer is on point. Mine probably stretches a bit by trying to be extensible.Burkitt
However, writing my own func would be the only way to parse that syntax in the way of natural speech (which inevitably becomes ambiguous and confusing in certain situations). "Am I good or bad?" "UNEXPECTED INPUT 'BAD' NOT RECOGNIZED"Sumikosumma
W
0

You can now use .includes:

![1, 2].includes(x);
Worcestershire answered 26/8, 2021 at 11:35 Comment(1)
This may answer the question. But I personally would not want to involve in any projects that includes these kind of code.Broom

© 2022 - 2024 — McMap. All rights reserved.