Shorten if else statement - javascript

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
}

Related

Beginner question: returning number value from string

If I give a value to firstParam as 'Ten' or '10' is there some way I can make the program return a number value to the function?
const sum = (firstParam, secondParam) => {
if (firstParam === Number(firstParam) && secondParam === Number(secondParam))
return (firstParam - secondParam)
else
return ('Invalid argument(s)')
}
console.log(sum(1,1))
EDIT
I have tried many different ways changing the firstParam to Number.firstParam, when i get close i miss out on the correct return statements
const sum = (firstParam, secondParam) =>{
firstParam = Number.firstParam
if (firstParam === Number(firstParam) && secondParam === Number(secondParam) )
return (firstParam - secondParam);
else
return ('Invalid argument(s)')
}
console.log(sum(1,1))
You need to check the type of the arguments before trying to convert them to a number:
const sum = (firstParam, secondParam) => {
// If both are numbers everything is ok
if (typeof firstParam === 'number' && typeof secondParam === 'number' ) {
return (firstParam - secondParam);
}
// If are stingified numebrs we convert them
const firstParamInNumber = parseFloat(firstParam)
const secondParamInNumber = parseFloat(secondParam)
return isNaN(firstParamInNumber) || isNaN(secondParamInNumber) ? 'Invalid argument(s)' : firstParamInNumber - secondParamInNumber
}
console.log(sum(1,'1'))
console.log(sum(1,1))
console.log(sum(1,'wrong param'))
If you provide a number in form of string. for example '10'.
You can parse it into Number and then return the sum as shown below.
Example when both arguments are correct.
const sum = (firstParam, secondParam) =>{
let sum = Number(firstParam)+Number(secondParam);
return Number(sum)?sum:"Invalid argument(s)";
}
console.log(sum('10','1'))
Example when anyone of the argument is incorrect.
const sum = (firstParam, secondParam) =>{
let sum = Number(firstParam)+Number(secondParam);
return Number(sum)?sum:"Invalid argument(s)";
}
console.log(sum('ten','1'))

js array filter based on two boolean conditions

I have two boolean conditions to filter an array. An array will always have 3 items within, and first condition always removes 2nd item, second condition 3rd one. And I successfully filtering it using .filter. But seems my approach a bit dirty, is there any better, clear way to filter?
const firstCondition = true;
const secondCondition = true;
const arrayToFilter: Array<string> = ['firstItem', 'secondItem', 'thirdItem'].filter(
(item, idx) =>
firstCondition && secondCondition
? item
: !firstCondition && secondCondition
? idx !== 1
: !firstCondition && !secondCondition
? idx === 0
: firstCondition && !secondCondition && idx !== 2
);
console.log(arrayToFilter);
Edit: Clarification
If Conditions are false they removes items
How about this?
const arrayToFilter: Array<string> = ['firstItem', 'secondItem', 'thirdItem'].filter(
(item, idx) => {
if (!firstCondition && idx === 1) return false
if (!secondCondition && idx === 2) return false
else return true
}
);
try,
....
(item, index) => (
(firstCondition && index !== 1)
|| (secondCondition && index !== 2)
|| true // (!firstCondition && !secondCondition)
)

How to implement this test on prototype of String object?

How to implement this valid function?
I want to implement a test function that returns true or false,
example : 'any-string-1'.valid('!empty'):
this is my valid.js file
function valid(str) {
if (
typeof str == "undefined" ||
!str ||
str === "" ||
str.length < 10 ||
!/[^\s]/.test(str) ||
/^.*-s/i.test(str)
) {
return true;
} else if (str.length > 30) {
return false;
}
}
module.exports = valid;
Assuming you are using Jest, you can use toBe:
const emptyStr = '';
const str = 'some-str';
expect(Boolean(emptyStr.length)).toBe(false); // it's empty, it's false because length is 0;
expect(str.length > 30).toBe(false); // it's false because length is not greather than 30;
expect(str.length < 10).toBe(true); // it's true because length is lower than 10;

What is the best way to avoid many if statements?

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)

Recursive palindrome check with JavaScript

I am trying to find out whether a string is a palindrome by recursion using javascript. But I can't figure out what I am missing in the code.
var firstCharacter = function(str) {
return str.slice(0, 1);
};
var lastCharacter = function(str) {
return str.slice(-1);
};
var middleCharacters = function(str) {
return str.slice(1, -1);
};
var isPalindrome = function(str) {
if(str.length < 2) {
return true;
} else {
if(firstCharacter(str) == lastCharacter(str)) {
isPalindrome(middleCharacters(str));
} else return false;
}
};
var checkPalindrome = function(str) {
console.log("Is this word a palindrome? " + str);
console.log(isPalindrome(str));
};
checkPalindrome("a");
//Program.assertEqual(isPalindrome("a"), true);
checkPalindrome("matom");
//Program.assertEqual(isPalindrome("motor"), false);
checkPalindrome("rotor");
//Program.assertEqual(isPalindrome("rotor"), true);
For sure something is wrong with the recursive call. I would love to have your help. Thanks. I am attaching the output of my code.
Here is another recursive palindrome.
function checkPalindrome(str){
if(str.length === 1) return true;
if(str.length === 2) return str[0] === str[1];
if(str[0] === str.slice(-1)) return checkPalindrome(str.slice(1,-1))
return false;
}
console.log(checkPalindrome('a')) // true
console.log(checkPalindrome('matom')) // false
console.log(checkPalindrome('rotor')) // true
You defined isPalindrome() to return a value, so if you call it yourself, recursively or otherwise, you need to deal with that return value. Also, your if ... else logic is too complicated, simplify:
var isPalindrome = function(str) {
if (str.length < 2) {
return true;
}
if (firstCharacter(str) == lastCharacter(str)) {
return isPalindrome(middleCharacters(str));
}
return false;
};
const isPalindrome = str => {
const strLen = str.length;
if (strLen < 2) return true;
if (str[0] === str[strLen - 1]) {
return isPalindrome( str.slice(1, strLen - 1) );
}
return false;
};
console.log(isPalindrome('madam'));
Using slice creates an array - if you want to compare the first and last char, you will need to extract the value from the array before applying == -
var firstCharacter = function(str) {
return str.slice(0, 1)[0] // <-- get the first element of the slice
}
var lastCharacter = function(str) {
return str.slice(-1)[0] // <-- get the first element of the slice
}
Here's another recursive solution that uses parameters l (left) and r (right) to check the string using indexes (rather than creating intermediate values with slice) -
const palindrome = (s = "", l = 0, r = s.length - 1) =>
r - l < 2
? true
: s[l] === s[r] && palindrome (s, l + 1, r - 1)
console.log
( palindrome ("motor") // false
, palindrome ("rotor") // true
, palindrome ("racecar") // true
, palindrome ("wow") // true
, palindrome ("i") // true
)
And here's a mutually recursive definition. It's wasteful but it has an elegant form nonetheless -
const pal = ([ s, ...more ]) =>
more.length === 0 || pal2 (more.reverse(), s)
const pal2 = ([ s, ...more ], q) =>
s === q && pal (more.reverse())
console.log
( pal ("motor") // false
, pal ("rotor") // true
, pal ("racecar") // true
, pal ("wow") // true
, pal ("i") // true
)
Here is another way to recursively check for a palindrome in JS:
function isPalindrome(str){
if (str[0] === str[str.length - 1] && str.length > 1) {
isPalindrome(str.substring(1, str.length -1))
return true
}else{
return false
}
}
Here's a simple answer for ya. Basically we are comparing the first character to last character and acting accordingly.
const isPalindrome = str => {
if (str.length <= 1) return true;
if (str[0] !== str[str.length - 1]) return false;
return isPalindrome(str.slice(1,-1))
}
const isPalindrome = str => {
// base case
if(str.length === 1) return true;
if(str.length === 2) return str[0] === str[1];
if(str[0] === str[str.length - 1]) {
return isPalindrome(str.slice(1, -1))
}
return false;
}
you can use recursion
base case
we have a base case (the simple case) if the string is one char we simply returns true.
if it has two chars we check if the first char is identical to the second and we return true if they are.
recursive case
if it is more than two chars we check if the first and last chars are identical or not if they are not we simply return false
but if they are identical so we now want to do the same thing with other chars so we call the same function with the same string but removing the first and last chars because we already know that they are identical and we keep going until we reach the base case.
hope this be useful
some tests
isPalindrome('p') // true
isPalindrome('po') // false
isPalindrome('pp') // true
isPalindrome('pop') //true
What's about this solution ?
function isPalindrome(str){
if (str.length > 3) return isPalindrome(str.substring(1, str.length-1));
return str[0] === str[str.length-1];
}
My simple implementation for a recursive palindrome check, in 2022:
function isPalindrome(str) {
if (!str.length || str.length === 1) return true;
return str[0] === str.at(-1) ? isPalindrome(str.substr(1, str.length - 2)) : false;
}
console.log(isPalindrome('catotac'));
Iterations breakdown:
// 1st iteration:
isPalindrome('catotac');
//2nd iteration
isPalindrome('atota');
//3rd
isPalindrome('tot');
// 4th iteration
isPalindrome('o'); // true

Categories

Resources