JS Ternary functions with multiple conditions? - javascript

I have been using a ternary operator in JavaScript to modify the value of an object based on user input. I have the following code, which runs as it should:
var inputOneAns = inputOne == "Yes" ? "517" : "518";
As you can see, I am assigning a numeric string value to inputOneAnswhether a user has inputed "Yes" or "No". However, there may be a case that a user has not selected a value (as it is not required). If this input was left blank, I would like to assign an empty string "" to inputOneAns. Is there a wayf or me to embed an ternary operator inside of another ternary operator? To help clarify, here is the same function that I want to accompolish with my ternary function but with if else statements?
if (inputOne == "Yes"){
var inputOneAns = "517"
}else if (inputOne == "No"{
var inputOneAns = "518"
}else{
var inputOneAns = ""
}
Is it possible to include multiple expressions into a ternary function? Is there a better way to accomplish what I am looking for? Thanks for the tips in advance.

Yes you can go wild nesting ternaries. I find this version to be fairly readable:
var foo = (
bar === 'a' ? 1 : // if
bar === 'b' ? 2 : // else if
bar === 'c' ? 3 : // else if
null // else
);
but that's not a widely shared opinion, and you should probably stick to if/else or switch when working on a team.

Yes, you can use multiple condition in Ternary Operator. Hope this will help you.
var x=20;
var y = x<13 ? "Child" : x<20 ? "Teenage" : x<30 ? "Twenties" : "Old people";
console.log(y);

A switch statement is likely the best choice in a situation like this.
let inputOneAns;
switch(inputOne) {
case "Yes":
inputOneAns = "517";
break;
case "No":
inputOneNas = "518";
break;
default:
inputOneNas = "";
}
If you could do ternary operations beyond 2 conditions, they would become incredibly messy. You can put conditions together, but I've no idea why you would want that - that would be incredibly messy.

The most elegant and clean way is to take advantage of Object literals:
const Switch = (str) => ({
"Yes": "517",
"No": "518",
})[str] || '';
console.log(Switch("Yes")); // 517
console.log(Switch("No")); // 518
console.log(Switch("Non matching value")); // Empty
This has the advantage of being both readable and flexible.

Yeh you can chain them together much like using an else if statement, but it can sometimes be a bit hard to read though, so I tend to split mine over multiple lines.
var inputOneAns = inputOne == 'Yes' ? '517' :
inputOne == 'No' ? '518' : '';
However in this case I would suggest a switch statement seeing as you're comparing the same value for every case.

var r = inputOne == "" ? "" : (
inputOne == "Yes" ? "517" : "518");

Unfortunately JavaScript does not provide a super terse and readable way to do this. Personally I would just use some single-line if statements like this:
var inputOneAns;
if (inputOne === 'Yes') inputOneAns = '517';
if (inputOne === 'No') inputOneAns = '518';
else inputOneAns = '';
Which can be even cleaner if you abstract it into a function (note: no need for else in this case):
function getInputOneAns(inputOne) {
if (inputOne === 'Yes') return '517';
if (inputOne === 'No') return '518';
return '';
}
Personally, I don't really like switch statements for this for two reasons: firstly those extra break statements bloating the code, and secondly, switch statements are very limiting - you can only do simple equality checks, and only against a single variable. Besides, in the case that you know you will be always checking a single string I would favour a simple map object:
var map = { 'Yes': '517', 'No': '518' };
var inputOneAns = map[inputOne] || '';

Yes, and it does provide a cleaner code than switch statement.. with all the breaks..
inputOne == "Yes" ? "517" :
inputOne == "No" ? "518" : inputOneAns = "";

Seems like a classic use for a switch statement:
let inputOneAns = '';
switch(inputOne) {
case 'Yes':
inputOneAns = "517";
break;
case 'No':
inputOneAns = "518";
break;
default:
inputOneAns = "";
}
note you don't actually need the default case, but I find it makes things more readable.

Related

Is there a better way to write this switch in JavaScript?

I have a switch with the following conditions:
The first case is or between three names (ROKA, MOKA and TOKA).
The second case is another name (KOKA) but with two additional conditions to display an alert.
Lastly, I have some other conditions to check inside the default block, as I'm unable to use a case for them.
This is my code:
var myname= 'JOKA';
var dhaba = false;
switch (myname) {
case ('ROKA'):
case ('MOKA'):
case ('TOKA'):
alert('EEE');
break;
case ('KOKA'):
// This will work as Goto to final default:
if (condition1 && condition2) {
alert('FEEE');
break;
}
default:
if (dhaba && myname != 'ROKA' && myname != 'TOKA') {
alert('TEEEE');
} else {
alert('CHEEE');
}
}
Is there a better way to write this code?
When you reach default, then myname is always unequal to the previously checked values. It is sufficient to use
default:
if (dhaba) {
alert('TEEEE');
} else {
alert('CHEEE');
}
I think switch is not the best option for your use case.
Also, as #NinaScholz has pointed out, the myname != 'ROKA' && myname != 'TOKA' will always be true, as otherwise you will fall in the first case.
Let's go step by step and see different ways to refactor your code:
πŸ‘Œ Simplified (Non-Switch) Code
The easies and most straightforward way to write your code is like this:
const myname = 'JOKA';
const dhaba = false;
if ('ROKA' === myname || 'MOKA' === myname || 'TOKA' === myname) {
alert('EEE');
} else if (myname === 'KOKA' && true && true) {
alert('FEEE');
} else {
alert(dhaba ? 'TEEEE' : 'CHEEE');
}
Note how the redundant checks have been removed and the last if - else block have been replaced with a ternary operator.
It is possible that your code is not exactly like the example you provided or that it changes overtime. In that case, you may consider other options other than the above simplified code.
πŸ‘‰ Checking multiple matches from a single variable using Array.prototype.indexOf()
However, you may have a lot more elements to check in the first if. In that case you could use an Array and Array.prototype.indexOf() to check if there's any match inside it (it will return -1 if there isn't any):
const myname = 'JOKA';
const dhaba = false;
if (['ROKA', 'MOKA', 'TOKA'].indexOf(myname) !== -1) {
alert('EEE');
} else if (myname === 'KOKA' && true && true) {
alert('FEEE');
} else {
alert(dhaba ? 'TEEEE' : 'CHEEE');
}
πŸ‘‰ N Input - Output (String) Pairs + Complex Default with Switch
It is also possible that you have multiple myname values that map to multiple alert() params, so you may feel tempted to write something like this:
const myname = 'JOKA';
const dhaba = false;
switch(myname) {
case 'XXX-1': alert('YYY-1'); break;
case 'XXX-2': alert('YYY-2'); break;
...
case 'XXX-N': alert('YYY-N'); break;
default:
if (myname === 'KOKA' && true && true) {
alert('FEEE');
} else {
alert(dhaba ? 'TEEEE' : 'CHEEE');
}
}
While this is fine and, actually, I think it is cleaner and less error-prone than checking an additional condition inside a case block, as you did in your example, and based on that do something and break or let the next block execute, I would advise you to consider using object literal lookups instead.
πŸ‘‰ N Input - Output (String) Pairs + Complex Default with Object Literals Lookups πŸ”Ž
There are multiple advantages to use them: better readability, easier debugging, maintainability, concision (no need to add break, for example)... I think the most important one for you, as you added the tag performance in your question, is that it is more performant.
This is because while the switch has to evaluate each case condition until it fins a break, so their order matters, the object lookup is just a hash table lookup, that is, O(1).
With this in mind, we could refactor the last example like this:
const myname = 'JOKA';
const dhaba = false;
const output = {
'XXX-1': 'YYY-1',
'XXX-2': 'YYY-2',
...
'XXX-N': 'YYY-N',
}[myname];
// Note output will be undefined if there isn't a match, so the first if
// will be evaluated to false in that scenario:
if (output) {
alert(output);
} else if (myname === 'KOKA' && true && true) {
alert('FEEE');
} else {
alert(dhaba ? 'TEEEE' : 'CHEEE');
}
πŸ‘‰ N Input - Output (String) Pairs + Single-Value Default with Object Literals Lookups πŸ”Ž and || (or)Β Operator
Also, note that if your default were just using another value inside the if, you could do that with a simple || operator:
const myname = 'JOKA';
const output = {
'XXX-1': 'YYY-1',
'XXX-2': 'YYY-2',
...
'XXX-N': 'YYY-N',
}[myname] || 'DEFAULT OUTPUT';
alert(output);
πŸ‘‰ N Input - Output (Arbitrary Code) Pairs with Object Literals Lookups πŸ”Ž
Note you could also execute arbitrary code for each case in your objects using functions or arrow functions:
const myname = 'JOKA';
const output = {
'XXX-1': () => { /* Do something... */ },
'XXX-2': () => { /* Do something... */ },
...
'XXX-N': () => { /* Do something... */ },
}[myname]();
...
Note that you could declare those functions above the object declaration and share them across multiple keys that should have the same behaviour:
const myname = 'JOKA';
const f1 = () => { /* Do something 1... */ };
const output = {
'XXX-1': f1,
'XXX-2': f1,
...
'XXX-N': () => { /* Do something... */ },
}[myname]();
...
For more on replace switchs with object literal lookups, take a look at this post: https://toddmotto.com/deprecating-the-switch-statement-for-object-literals

How to reduce "if statement" conditions? [reduce the conditions inside the if statement]

after days of hard thinking i choose to ask that question. I have if statement with multiple conditions:
//var current is array of arrays of integers
if((current[rot][0] + x)<blocks.length
&& (current[rot][1] + x)<blocks.length
&& (current[rot][2] + x)<blocks.length
&& (current[rot][3] + x)<blocks.length
&& !$(blocks[current[rot][0]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][1]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][2]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][3]+x]).hasClass("blockLand"))
{
//something to happen here ONCE!
}
Because i want something inside to happen just once i think i cant use for loop.
So my question is: is there a possible way to reduce the conditions number? and how?
P.S.: Yes i figured out that i can use flag (true/false) inside and do my stuff outside this if, in another if - but i think that not always gonna work, because for every loop the flag will be different.
var b = true;
for (var i = 0; i <= 3; i++) {
// In two lines for being clear, but it's possible just in one
b = b && (current[rot][i] + x)<blocks.length
b = b && !$(blocks[current[rot][i]+x]).hasClass("blockLand");
// You could speed it up this way.
if(!b) break;
}
if (b) {
//something to happen here ONCE!
}
I think I understand what you are asking but let me know if there is anything else I can do.
JavaScript has a ternary (conditional operator) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
This operator allows you to assign true/false values based on an internal if/else condition.
Here is some code for you to explain this...
window.onload = function() {
var one = 1;
var two = 2;
console.log(one > two ? "greater" : "not greater");
};
You can also use a Switch statement which you can read about here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch.
Here is an example of a switch statement.
window.onload = function() {
var string = "testing this out";
switch (string) {
case "testing this out":
console.log('testing this out found in condition one');
break;
case "testing":
console.log('found testing');
break;
default:
console.log('not found');
break;
}
};
Let me know if I can improve this.

Combine if/else into one statement? (Javascript)

function changeButton () {
if (event.currentTarget.className == 'btnRed') {
event.currentTarget.className = 'btnGreen';
} else {
event.currentTarget.className = 'btnRed';
}
}
Let's say I have the above code. I have seen similar codes written that would combine these two, but I don't really remember how it did it. It was something like className = (btnGreen | btnRed).
I am very sorry for the vagueness of this question.
You can use the ternary operator (condition) ? (true) : (false)
event.currentTarget.className = event.currentTarget.className == 'btnRed' ? 'btnGreen' : 'btnRed';
I would go a little bit further, extract the strings into variables to remove the ability to mistype them across the solution. And refactor event.currentTarget into a variable.
var RED_BUTTON_CLASS = 'btnRed',
GREEN_BUTTON_CLASS = 'btnGreen';
var currentTarget = event.currentTarget;
currentTarget.className = currentTarget.className == RED_BUTTON_CLASS ? GREEN_BUTTON_CLASS : RED_BUTTON_CLASS;
This I feel will just make it easier in the long run, completely optional
Edit
So adding extra information from what Jan said.
var RED_BUTTON_CLASS = 'btnRed',
GREEN_BUTTON_CLASS = 'btnGreen';
These probably describe a state, so you could better name them:
var ERROR_BUTTON_CLASS = 'btnRed',
OK_BUTTON_CLASS = 'btnGreen';

how we can covert a string to boolean? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I convert a string to boolean in JavaScript?
I have a select list with 2 options in it, yes or no, something like:
<select size="1">
<option value="true">yes</option>
<option value="false">no</option>
</select>
Now i want to use the selected value in the jquery-UI button disabled property , means :
$("button").button({ disabled : $("select").val() });
Now my problem is that the value which we will get by $("select").val() is string and for
disabled property we need boolean. So i want to know that is there any method just like
pareInt or parseFloat by which we can convert a string to boolean ?
var value = ('true' === $("select").val() );
You can use the third one:
var num = +something; //toNumber
var str = something + ""; //toString
var bol = !!something; //toBoolean
That will turn 0, "", false, null, undefined, NaN to false, and everything else to true
But using my deduction powers, you want something like "false" -> false, for this you can use one of these:
var bol = something === "true"; //false for anything different than true
var bol = something !== "false"; //true for anything different than false
var myBoolean = (myString === 'true') ? true : false;
Something like
$("select").val() == 'true'
should do the trick.
Depends how many times you want to do it. If its going to be littered throughout your code I would add in a function like:
Boolean.parse = function (str) {
switch (str.toLowerCase ()) {
case "true":
return true;
case "false":
return false;
default:
throw new Error ("Boolean.parse: Cannot convert string to boolean.");
}
};
Try with this code:
var myBool = myString == "true";
How about writing your own?
I'm not exactly firm in JavaScript Syntax but try this:
function a(inputString)
if(inputString == "true")
return true;
if(inputString == "false")
return false;
I'm sure there are better solutions. This one is just from the top of my head.

Another way of writing an if statement?

It may sound a bit stupid, but is there a shorter way of writing the following if statement in less words :
if(auxiliars.environment == "Development") {
less.env = "development";
less.watch();
}
Because I have that statement as part of a function :
set_environment: function(environment) {
if(auxiliars.environment == "Development") {
less.env = "development";
less.watch();
}
}
And I was wondering if I can somehow return that two lines of code :
less.env = "development";
less.watch();
The main reason I'm asking is because in PHP I'm doing something like the following :
return (!empty($len)) ? hash('sha512', str_pad($stream, (strlen($stream) + $len), substr(hash('sha512', $stream), $this->round(strlen($stream) / 3, 0), ($len - strlen($stream))), STR_PAD_BOTH)) : hash('sha512', substr($stream, $this->round(strlen($stream) / 3, 0), 16));
And I was wondering if I can do something similar in JavaScript.
Not really, why would you want? Your if statement is clean and easily to understand.
Yet, you might try the ternary operator:
auxiliars.environment == "Development"
? ( less.env = "development", less.watch() )
: void 0;
But using the comma operator doesn't make your code better.
Javascript has the ? : statement, if that's what you are asking.
So
var x = 5;
var y = (x < 10) ? "bar" : "foo";
will assign the string "bar" to y.
Yes, you can use the ternary operator

Categories