Shorthand for if sentence - javascript

Why I am asking
I have been having a lot of trouble understanding the shorthand for the if sentence in JavaScript, and I haven't found an article or tutorial that described it well. And that's why I am stuck opitimizing my little code. And I am new to JavaScript, so if someone could give me a basic understanding of the shortning of this code, I would very much appreciate you telling me the magic behind the code.
What I need help with
I am going to use the exact same code in a lot of functions. Therefore, I want to optimize it and make it shorter version of the code.
function welcomemessage() {
if (br == 1) {
hello();
}
else {
hey();
}
}

Use the ternary operator.
function welcomemessage() {
(br == 1) ? hello() : hey();
}
The ternary operator is useful, and not difficult to understand. here's how it works.
(condition) ? (true) : (false)
Edit:
Since JS treats functions as first class objects, it is possible to create a wrapper. Something like below (not tested though)
function ternaryWrapper(br, functionTrue, functionFalse){
return (br == 1) ? functionTrue : functionFalse;
}
//call it
ternaryWrapper(2,hello, hey);

Even shorter:
function welcomemessage(br){
[hello,hey][br-1](); //This will work.
}
welcomemessage(1); //hello();
welcomemessage(2); //hey();
Fun Fact:1
To make your script hard to read for someone else, do it like this:
function welcomemessage(){
return br==1 && (hello(),1) || (hey(),1); //This will work too.
}
1 Totally not related to the answer.
Update
var something = ( (br == 1) ? hello() : hey() );
something will be the value hello() or hey() returned.

Or:
var msgfuncs = [ hey, hello ];
function welcommessage() { msgfuncs[br](); }
(assumes that when "br" isn't 1 it's 0, which of course may be an invalid assumption.)
If the choice is made with different functions, just put the array directly in the surrounding function:
function welcomemessage() {
[ hey, hello ][br]();
}
If you want to make the decision and save the function to call later, you can do this:
var messageFunction = [ hey, hello ][ br ];
then any time later:
messageFunction();

In case br is always be numeric, the xbonez answer can be optimized a little bit by using strict comparison === (because it is a little bit faster):
function welcomemessage() {
(br === 1) ? hello() : hey();
}
And another interesting option is:
function welcomemessage() {
(br - 1) ? hey() : hello();
}
This last function works because when br is 1, it will turn to 0 (which is a falsish value) and evaluate to false, triggering hello(), and for the rest it will trigger hey()

Related

If else if shortening

I can see there are so many related questions to this. Could not find anything specific addressing my query. Here is my question:
How can i shorten the below if else condition:
If (condition1)
{
If(condition2)
{
Logic A
}
}
Else if (condition3)
{
Logic A
}
One way i could come up was as below:
If (condition1 && condition2 || !condition1 && condition3)
{
Logic A
}
Just wondering if there is a better way of doing it?
In this case optimization is important only from readability point of view. From OP examples I would prefer original one, because it easier to follow for developer/reader who didn't write this code.
We execute one action or do nothing based on conditions, so I would wrap every condition chain which leads to the execution into the method with descriptive name and used them with or operator.
// condition 1 = customer.persisted
// condition 2 = bonuses.has(customer.id)
// condition 3 = promotionCodes.has(customer.promotionCode)
function whenExistingCustomerWithBonus() {
return customer.persisted && bonuses.has(customer.id);
}
function whenGuestCustomerWithPromotionCode() {
return customer.persisted === false && promotionCodes.has(customer.promotionCode);
}
// Usage
if (whenExistingCustomerWithBonus() || whenGuestCustomerWithPromotionCode()) {
// execute logic A
}
you can do this
(condition1 && condition2 || !condition1 && condition3) ? logic(a) : logic(b)
Its called Ternary operator, It would make your code shorter and you can also use it to set a variable, for example
const isTrue = 4 > 3 ? true : false
There are some aspects that you must keep in mind.
It's possible that a shorter code be faster in some script languages (like JavaScript, PHP...).
But it worth? Is your if inside a loop long enough to make any difference in your code execution time?
Do your shortened code makes easier or harder to understand your code? Sometimes joining some if conditions inside a boolean logic makes it easier to understand, but sometimes it's so complicated that is very hard to understand.
sometimes its possible to simplify (note the use of the word 'simplify' instead of 'shorten') conditional logic by reversing it, or by delegating logic to other functions, or a combination of both:
given this:
function performLogic() {
if (condition a) {
if (condition b) {
logic 1
}
} else {
logic 1
}
}
let's try to think about this in reverse:
function performLogic() {
if (!condition a) logic 1
else if (conditoin b) logic 1
}
keep in mind this kind of refactor will not always be possible, and i also advise you to write unit tests for the logic to ensure that the end result remains the same.
It can also sometimes be simplified further depending on the logic in the function. many times we can replace conditional logic with guard clauses like this:
function getSomeValue() {
if (condition a) {
if (condition b) {
... do some logic
return someValue;
}
}
}
this can be changed to
function getSomeValue() {
if (!condition a) return;
if (!condition b) return;
... do some logic
return someValue;
}

simplify if else statement

I have some functionality dependent on many conditions. All variables in conditional statements are boolean variables and the code is the following and I don't like it:
if (userHasMoreThanOneMarket && isOnlyMarketSelected || !userHasMoreThanOneMarket && userHasMoreThanOneAgency) {
if (isOnlyAgencySelected) {
//do case 1
} else if (noAgencySelected && isOnlyMarketSelected) {
//do case 2
}
}
Is there a way to make it more understandable and nice?
That's about as concise as you're going to get with JavaScript. I suppose if you really wanted to, you could create variables to store your binary options:
var multiMarketOneSelected = userHasMoreThanOneMarket && isOnlyMarketSelected;
var singleMarketMultiAgency = !userHasMoreThanOneMarket && userHasMoreThanOneAgency;
if (multiMarketOneSelected || singleMarketMultiAgency) {
if (isOnlyAgencySelected) {
//do case 1
} else if (noAgencySelected && isOnlyMarketSelected) {
//do case 2
}
}
Though I don't really know if you gain much readability from that.
Your code seems fine, but if you don't like it you could do something like this (note that the only improvement here is style, if you like it better):
function check(){
return {
valid: userHasMoreThanOneMarket && isOnlyMarketSelected || !userHasMoreThanOneMarket && userHasMoreThanOneAgency,
case: [
isOnlyAgencySelected,
noAgencySelected && isOnlyMarketSelected
]
};
}
var conditions = check();
if (conditions.valid) {
if (conditions.case[0]) {
//do case 1
} else if (conditions.case[1]) {
//do case 2
}
}
Some things I would try to make the code more readable:
Initialise the variables in a way that you don't have to negate them again. So !userHasMoreThanOneMarket becomes userHasOneMarket
isOnlyMarketSelected sounds redundant to me. And you are checking it in the outer if-clause and the inner again.
You probably have a lot of code above this code snippet to initialise and set all this boolean values. Try return; statements after each variable to get rid of if-conditions.
I hope this helps.

What is this pattern f(a)(b)(c) called?

function setStyle(x) {
with (x.style) {
padding = '10px'
marginBottom = '10px'
width = '100%'
}
return setStyle
}
setStyle(account)(password)(login)
I often use the above pattern, but when I need to talk about it, I have no idea what is it called? How to refer to this kind of approach in the conversation?
UPDATE:
Someone closed this question as duplicate, but I cannot see why is that a duplicate. Other question is about some framework, the poster is trying to understand the code. I do not try to understand the code, I am asking about an English term for a known pattern. Even though the discussed concept is the same, the question is different. It is like saying that "Who was the youngest in Jasckson's Five" and "Whose album is Thriller" both are the same question, only because it happens to be about the same person. But those are different questions, not the same.
This pattern is not "function chaining", because chained (=composed, pipelined) functions work by passing result of one function as an argument to the next one. For example, if you have something like:
str = removeBadChars(str)
str = makeLowerCase(str)
str = convertToURL(str)
you can rewrite this more concisely as
str = chain(removeBadChars, makeLowerCase, convertToURL)(str)
(Exercise: write chain()).
Your pattern doesn't appear to have a name, probably because it's fairly useless. Mr. Crockford coined the term retursion,
but it doesn't seem to be used widely.
Note that this pattern is essentially anti-functional, because in functional programming we prefer to work with pure functions, while a "retursive" function can only do anything useful as a side effect.
UPD: this reasoning applies to functions that just blindly return itself, like in your example, however, the f()()() syntax can also be used with functions that return something else on each invocation. In this case, the "root" function accepts a hidden parameter ("accumulator") used to carry state around. A good example of such approach would be chain() like above, but written in the applicative style: chain(func1)(func2)(func3):
function chain(f, fun) {
fun = fun || function(x) { return x };
if(typeof f != "function")
return fun(f);
return function(x) {
return chain(x, function(y) { return f(fun(y)) })
}
}
// Example:
makeLowerCase = function(str) { return str.toLowerCase() };
removeBadChars = function(str) { return str.replace(/\W/g, "") };
makeURL = function(str) { return "http://" + str };
funcs = chain(makeLowerCase)(removeBadChars)(makeURL);
x = funcs('!!! HELLO ???');
alert(x);
In this case, this syntax is used to implement "partial application", because we return a closure which calls the root function yet again, with a predefined second argument.

Better method of checking a bunch of conditions

I'm new to javascript and still coming to terms with the language's nuances.
I have a piece of code where I have to check a set of conditions on a particular variable.
if (a=="MAIN_DOMAINNAME" || a=="DOMAIN_SERIAL" || a=="DOMAIN_REFRESH" || a=="DOMAIN_RETRY" || a=="DOMAIN_EXPIRE" || a=="DOMAIN_NEGTTL" || a=="MAIN_NS") {
Is there a better way to do this conditional check, like say:
if a is one of ("DOMAIN_SERIAL", "MAIN_DOMAINNAME", "DOMAIN_REFRESH" ) {?
Assuming a relatively modern browser, you can use Array.indexOf (spec)
if (["DOMAIN_SERIAL", "MAIN_DOMAINNAME", "DOMAIN_REFRESH"].indexOf(a) !== -1)
Note - you can easily shim it for older browsers (see the mdn link on how).
A regex would be shorter and works everywhere :
if ( /^(MAIN_DOMAINNAME|DOMAIN_SERIAL|DOMAIN_REFRESH|..)$/.test(a) ) {
// do stuff
}
FIDDLE
var ars = ["DOMAIN_SERIAL", "MAIN_DOMAINNAME", "DOMAIN_REFRESH"];
if(ars.some(function(ar){ return a === ar; })){
// do smth
}
Should mention the switch statement as it should be working fine with the example given in the question.
switch(a) {
case('MAIN_DOMAINAME'):
case('DOMAIN_SERIAL'):
case('DOMAIN_REFRESH'):
case('DOMAIN_RETRY'):
console.log('Go wild.');
break;
}
Not as lightweight as the other answers, but it's readable and matches (a === b).
I prefer the regex solution already provided by adeneo, but if you want something that matches the
if a is one of (...
wording from the question reasonably closely you can do this:
if (a in list("MAIN_DOMAINNAME", "DOMAIN_SERIAL", "DOMAIN_REFRESH", "DOMAIN_RETRY")) {
// do something (rest of list omitted to avoid scrolling)
}
by providing a helper function to turn the list into an object:
function list() {
var o={}, i;
for (i=0; i < arguments.length; i++) o[arguments[i]] = true;
return o;
}
Of course you can omit the helper function and just use an object literal, but that's ugly:
if (a in {"MAIN_DOMAINNAME":1, "DOMAIN_SERIAL":1, "DOMAIN_REFRESH":1}) {

Ternary Operators as short conditional statements

Is there anything wrong with using ternary operators in place of longer conditional statements in Javascript, for instance using:
(variable == "dog") ? dog_stuff() : false;
Rather than
if ( variable == "dog" )
{
dog_stuff();
}
This may sound like a stupid question but I just find it's pretty quick and easy to read, I just don't want to be using it if there's a possible drawback?
You could also write
(variable == 'dog') && dog_stuff();
if you don't have an else statement.
A few lines from backbone.js:
options || (options = {});
models = _.isArray(models) ? models.slice() : [models];
model = this.getByCid(models[i]) || this.get(models[i]);
You can group multiple statements, if it's very necessary:
(1==1) && (a=2,b=3)
alert(a); // 2
alert(b); // 3
It's wrong because you're telling your code to execute false. Imagine the following code:
if ( variable == "dog" )
{
dog_stuff();
} else {
false;
}
IMO the 4 line conditional function call is perfectly fine. You can shorthand it to:
if (variable == "dog") dog_stuff();
The only problem with this is if you comment it out, or add 1 more function then things look correct, but don't execute correctly:
if (variable == "dog") dog_walk(); dog_bark(); // dog_bark executes always!
if (variable == "dog") // dog_walk();
earn_cash(); // suddenly earn_cash() is dog-dependent.
As long as the format is easily understood by you and anyone else that may need to read the code, it's fine.

Categories