58

I have some code with a lot of if/else statements similar to this:

var name = "true";

if (name == "true") {
    var hasName = 'Y';
} else if (name == "false") {
    var hasName = 'N';
};

But is there a way to make these statements shorter? Something like ? "true" : "false" ...

cookie monster
  • 10,671
  • 4
  • 31
  • 45
Meek
  • 3,086
  • 9
  • 38
  • 64

8 Answers8

154

Using the ternary :? operator [spec].

var hasName = (name === 'true') ? 'Y' :'N';

The ternary operator lets us write shorthand if..else statements exactly like you want.

It looks like:

(name === 'true') - our condition

? - the ternary operator itself

'Y' - the result if the condition evaluates to true

'N' - the result if the condition evaluates to false

So in short (question)?(result if true):(result is false) , as you can see - it returns the value of the expression so we can simply assign it to a variable just like in the example above.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
  • 1
    It doesn't scale really well, look at my answer or @BenjaminGruenbaum answer – Abijeet Patro Aug 16 '13 at 08:54
  • Several reasons, first of all you're mixing `"` and `'` for string literals which creates a false notion that they somehow represent different things. Second of all using the `==` operator [is frowned upon](http://stackoverflow.com/a/359509/1348195). Moreover, inline ternary blocks are harder to read than if statements (I prefer the original code) and don't pass code reviews in many companies. Also, your spacing is off. – Benjamin Gruenbaum Aug 16 '13 at 08:55
  • @TusharGupta Asking someone to accept your answer is considered rude around here (see relevant meta threads). Moreover - OP will gain more by waiting for an hour or two and see what the community thinks about these answers before accepting any. – Benjamin Gruenbaum Aug 16 '13 at 08:59
  • @BenjaminGruenbaum i am just asking him to accept the answer but not mine he has his choice to select the answer.I just want he accept the answer of anybody n close the chapter – Tushar Gupta - curioustushar Aug 16 '13 at 09:01
  • @TusharGupta you could keep your answer just as valid and fix the problems with it like mixing `"` and `'` for no reason, the inconsistent indentation, and so on. I think the downvotes relate to that and not the actual content, though I did not downvote myself so I can't really tell. – Benjamin Gruenbaum Aug 16 '13 at 12:36
  • 1
    @TusharGupta Thanks for fixing it, I've made some clarifications (notably, formatting and adding links to the spec and to a reference). Feel free to revert any changes you don't like. – Benjamin Gruenbaum Aug 16 '13 at 15:24
  • shouldn't it be **(name == 'true')** with only 2 equality symbols? – Adam Jan 26 '16 at 12:08
  • 1
    @Adam - using three symbols requires the values to be of the same *type* as well as the same *value* whereas using two symbols would do a conversion before checking the values: 2 == '2' would evaluate to true even though one is a string and the other is a number. 2 === '2' would evaluate as false because the two values are not of the same type. Quick demo here if you want it :) https://jsfiddle.net/c5fabevq/ – Mark Townsend Oct 11 '17 at 09:14
30

You can use an object as a map:

  var hasName = ({
        "true"  : "Y",
        "false" : "N"
  })[name];

This also scales nicely for many options

  var hasName = ({
        "true"          : "Y",
        "false"         : "N",
        "fileNotFound"  : "O"
  })[name];

(Bonus point for people getting the reference)

Note: you should use actual booleans instead of the string value "true" for your variables indicating truth values.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • 1
    (Of course, the map doesn't have to be anonymous, if you name it, that's even better for readability in most non-obvious cases, readable code is more important than shorter code. While we all want to write concise code - it should never be in expense of clarity) – Benjamin Gruenbaum Aug 16 '13 at 08:58
  • 2
    Nice solution! Wouldn't have thought of that. But i guess that using the index-operator will result in the same if/elseif construct in machine code. – konqi Aug 16 '13 at 09:10
  • @JoSo That depends on the implementation, but they would be equally fast on a clever run-time :) I use this construct in place of switch... case on strings a lot. – Benjamin Gruenbaum Aug 16 '13 at 10:59
  • I aggree that a switch with strings would probably be equally fast / slow. In any other case (integers, booleans) the switch would be faster because the ALU of the CPU can handle it with ease. If you have to consider this in JavaScript - i do not know. – konqi Aug 16 '13 at 14:20
21

Try this

hasName = name ? 'Y' : 'N';
Eswara Reddy
  • 1,617
  • 1
  • 18
  • 28
19

?: Operator

If you want to shorten if/else you can use ?: operator as:

condition ? action-on-true : action-on-false(else)

For instance:

let gender = isMale ? 'Male' : 'Female';

In this case else part is mandatory.

I see this kinda short hand format use for null/undefined checking like:

const avatarName = user.firstname ? user.firstname : user.lastname;

However in this case you can simply use:

const avatarName = user.firstname ?? user.lastname;

or

const avatarName = user.firstname || user.lastname;

To see the difference check this out

&& Operator

In another case, if you have only if condition you can use && operator as:

condition && action;

For instance:

!this.settings && (this.settings = new TableSettings());

FYI: You have to try to avoid using if-else or at least decrease using it and try to replace it with Polymorphism or Inheritance. Go for being Anti-If guy.

Mohammad Jamal Dashtaki
  • 1,415
  • 1
  • 16
  • 23
10

Try like

var hasName = 'N';
if (name == "true") {
    hasName = 'Y';
}

Or even try with ternary operator like

var hasName = (name == "true") ? "Y" : "N" ;

Even simply you can try like

var hasName = (name) ? "Y" : "N" ;

Since name has either Yes or No but iam not sure with it.

GautamD31
  • 28,552
  • 10
  • 64
  • 85
5

Most answers here will work fine if you have just two conditions in your if-else. For more which is I guess what you want, you'll be using arrays. Every names corresponding element in names array you'll have an element in the hasNames array with the exact same index. Then it's a matter of these four lines.

names = "true";
var names = ["true","false","1","2"];
var hasNames = ["Y","N","true","false"];
var intIndex = names.indexOf(name);
hasName = hasNames[intIndex ];

This method could also be implemented using Objects and properties as illustrated by Benjamin.

Community
  • 1
  • 1
Abijeet Patro
  • 2,842
  • 4
  • 37
  • 64
1

Try this method;

Shorthand method:

let variable1 = '';

let variable2 = variable1 || 'new'
console.log(variable2); // new

Longhand method:

 let variable1 = 'ya';
 let varibale2;

 if (variable1 !== null || variable1 !== undefined || variable1 !== '')
       variable2 = variable1;

console.log(variable2); // ya
Ericgit
  • 6,089
  • 2
  • 42
  • 53
0

Try This

var name = "true";
var hashname;
     name
      ? hashname = "Y"
      : !name
       ? hashname = "N"
       : ""

     console.log(hashname)