What is the best way to avoid many if statements? - javascript

What is the best and ellegant way for refactoring the following if statements?
if (!this.props.isRequired) {
return false
}
if (items.length < 1) {
return false
}
if (items.length === 1) {
return true
}

Use || to alternate between all conditions that will return the same value:
if (!this.props.isRequired || items.length < 1) {
return false
}
if (items.length === 1) {
return true
}

I think you should handle the case where items.length is > 1, too:
return (this.props.isRequired && items.length === 1);
You can omit the if and just return the boolean true/false value directly.

if (!this.props.isRequired || items.length < 1) {
return false
}
else if (items.length === 1) {
return true
}

You could use a ternary operator:
return !this.props.isRequired ? false : (items.length === 1)

Try using a ternary
this.props.isRequired || items.length < 1 ? return false: null;
items.length === 1 ? return true: null;

It depends how you write business logic !!!
Now in above code you can merge first two if statements in one as both returns same value.
if (!this.props.isRequired || items.length < 1) {
return false
}
if (items.length === 1) {
return true
}

If I were to come across these exact lines during refactoring (or review), I'd immediately look for the next/last return statement, as these lines appear to indicate the function has multiple output types.
Having different return types is something I try to avoid in general.
As for the reduction in if statements; my first step would be to make the if statements conclusive, which seems to come down to answering the question whether items.length would be valid if it's greater than 1.
If so, you can turn it into a single statement.
return this.props.isRequired && items.length >= 1;
If not, you can use the non-conclusive part (> 1) condition (or the inverse, to make it more concise)
if (items.length <= 1) {
return this.props.isRequired && items.length === 1;
}
// the alternative flow (not in your example)

Related

Shorten if else statement

How can I shorten that if else statement?
const isPathPointAvailable = (requiredItems?: ModelTypes['Item'][], oneOfItems?: ModelTypes['Item'][]) => {
if(requiredItems && requiredItems.length > 0){
return userHaveMultipleRequiredItems(requiredItems);
}
if(oneOfItems && oneOfItems.length > 0){
return userHaveRequiredItem(oneOfItems);
}
return true
I tried this but it always return true
const isPathPointAvailable = (requiredItems?: ModelTypes['Item'][], oneOfItems?: ModelTypes['Item'][]) => {
requiredItems && requiredItems.length > 0 && userHaveMultipleRequiredItems(requiredItems);
oneOfItems && oneOfItems.length > 0 && userHaveRequiredItem(oneOfItems);
return true
};
Use the optional chaining operator ?. to return the falsy undefined if the arrays are not defined. length === 0 is also falsy.
const isPathPointAvailable = (requiredItems?: ModelTypes['Item'][], oneOfItems?: ModelTypes['Item'][]) => {
if(requiredItems?.length) return userHaveMultipleRequiredItems(requiredItems);
if(oneOfItems?.length) return userHaveRequiredItem(oneOfItems);
return true
You were on the right track with your second attempt, but it is missing the return statements in the shortened ifs.
You could also just use a simple lambda to refactor those two longer checks with something like:
let hasElements = (arr) => arr && arr.length > 0;
const isPathPointAvailable = (requiredItems?: ModelTypes['Item'][], oneOfItems?: ModelTypes['Item'][]) => {
if( hasElements(requiredItems) ) return userHaveMultipleRequiredItems(requiredItems);
if( hasElements(oneOfItems) ) return userHaveRequiredItem(oneOfItems);
return true
}

Loop thru array to make sure criteria is met on every item

I have an array of items. I want to make sure every item meets a certain criteria.
I wrote this for loop but I'm not sure if it's the most efficient. Is there a better way to do this?
let match = 0;
for (var i = 0; i < lastPressed.length; i++) {
if (lastPressed[i].o.length === 1 && lastPressed[i].n.length === 0) {
match++;
} else {
break;
}
}
if(match === lastPressed.length) return true;
return false;
Javascript has a function just for this: Array.prototype.every.
return lastPressed.every(v => v.o.length === 1 && v.n.length === 0);
Using builtin every is the best choice here.
However, assuming you want to do it by yourself (for fun, for learning), notice that you don't have to check every item in the array. It's because the very first item that doesn't match the criteria should fail the whole process.
You just have to reverse the condition then. You don't need the count.
for (var i = 0; i < lastPressed.length; i++) {
if (!(lastPressed[i].o.length === 1 && lastPressed[i].n.length === 0)) {
return false;
}
}
return true;
It's exactly your code but the loop terminates when you find the first nonmatching element.
You could take a for ... of statement and exit early.
This approach uses a destructuring assignment and a negated condition for the check.
for (const { o, n } of lastPressed) {
if (o.length !== 1 || n.length !== 0) return false;
}
return true;

How do I return true or false for ternary operator in Javascript?

I'm trying to convert the code below to a shorthand version with a ternary operator
if (sum % 10 === 0) {
return true;
} else {
return false;
}
It works fine as is, but when I change it to
sum % 10 === 0 ? return true : return false;
I get a syntax error, and when I change it to
sum % 10 === 0 ? true : false;
it doesn't work as intended.
If anyone can enlighten me as to what's going on, I'd be much appreciated.
The expression (sum % 10 === 0) is boolean itself, so just return it:
return sum % 10 === 0
You can simply do:
return !(sum % 10)
if (sum % 10) === 0, then !(sum % 10) will return true, else false.
What you tried:
sum % 10 === 0 ? return true : return false;
This does not work, because return is a statement and not an expression. A statement can not be used inside of an expression.
sum % 10 === 0 ? true : false;
This works, but without a return statement, it is just an expression without using it.
Finally, you need to retur the result of the conditional (ternary) operator ?:, like
return sum % 10 === 0 ? true : false;
For a shorter approach you could return the result of the comparison without ternary.
return sum % 10 === 0;

How to catch null, undefined, blank values with AngularJS filter

I'm attempting to write a filter for use in a grid that will catch all null, undefined, blank string, or other similar values and display a dash "-". I've written the following so far, but it doesn't catch null values, and I'm wondering if it could be more succinct and possibly refactored to avoid three layers of nested if/else statements. Percentage values need to be checked that they're over 0 and under 1. Also, negative numbers and 0's should be returned as is. Thanks!
angular.module('AdverseEventsExplorer.main').filter('emptyCellFilter', function ($filter) {
return function (input, cellFilter, args1, args2) {
if (cellFilter == undefined) {
return (angular.isNumber(input) || angular.isDefined(input) && input.length > 0) ? input : '-';
} else {
if (cellFilter.match(/pctg|percent|pctgFilter|incidence/ig)) {
return (input > 0 && input < 1.0000000) ? $filter(cellFilter)(input, args1, args2) : '-';
} else {
return (angular.isNumber(input) || angular.isDefined(input) && input.length > 0) ? input : '-';
}
}
};
});
Version 2.0 taking into account #tymeJV's comment:
angular.module('AdverseEventsExplorer.main').filter('emptyCellFilter', function ($filter) {
return function (input, cellFilter, args1, args2) {
if (!cellFilter) {
return (angular.isNumber(input) || (input)) ? input : '-';
} else {
if (cellFilter.match(/pctg|percent|pctgFilter|incidence/ig)) {
return (input > 0 && input < 1.0000000) ? $filter(cellFilter)(input, args1, args2) : '-';
} else {
return (angular.isNumber(input) || (input)) ? $filter(cellFilter)(input, args1, args2) : '-';
}
}
};
});
Whenever you encounter a function that's getting too complex to refactor try extracting some of the smaller statements to concisely named variables. It makes it much easier for our brains to keep track of the function's requirements, and it's also more readable to new devs reading your code.
var inputHasValue = angular.isNumber(input) || input;
if(!inputHasValue){
return '-';
}
if (!cellFilter) {
return input;
}
var isPercentageCell = cellFilter.match(/pctg|percent|pctgFilter|incidence/ig);
var valueIsInRange = input > 0 && input < 1;
if(!isPercentageCell || valueIsInRange){
return $filter(cellFilter)(input, args1, args2);
}
return '-';
typeof x ==='number' || !!x
is false when x is null, undefined or empty string
Only one case in which it doesn't work – if you need to filter boolean variables, but your case doesn't seem to need it.
Anyway in that case you can use
typeof x === 'boolean' || typeof x ==='number' || !!x

'if'-'else' in JavaScript

I have a simple if - else construct that operates with data grid filterind. Like this:
if (_r1 <= _r3 && _r3 <= _r2) {
return true;
}
else {
return false;
}
where _r1, _r2, _r3 and numbers. It has both true and false. Is it possible to rewrite this construction that it will has only for example true branch and will go to the else branch by default?
P.S. (if ... ? ... : ...) is not what I want.
Use:
return _r1 <= _r3 && _r3 <= _r2;
if (_r1 <= _r3 && _r3 <= _r2) {
return true;
}
return false;

Categories

Resources