Is there an efficient way to add two variables a and b when they could be dynamic? I also need to check if their types are numbers. I think the way I have described below is not the best/modern way to implement this. Please help.
EDIT
I also want to make sure if one the variable is not a number(or null) then the variable C gets its value from the variable which is the number . How can I do it?
const a;
const b;
let c;
// variables a and b are dynamic and could be null.
if(typeOf(a)==='number' && typeOf(b)==='number'){
if(!a && b){
c=b
}
if(a && !b){
c=a
}
if(a && b){
c=a+b
}
}
You can simply check with typeof and use the logical or operator to convert NaN to 0.
if(typeof a ==='number' && typeof b === 'number'){
c = (a || 0) + (b || 0);
}
To also allow invalid values to be treated as 0, you can use this:
c = (typeof a === 'number' ? (a || 0) : 0) + (typeof b === 'number' ? (b || 0) : 0)
It could also be written like so:
c = (typeof a === 'number' && !isNaN(a) ? a : 0) + (typeof b === 'number' && !isNaN(b) ? b : 0)
I think you're looking for
const c = (typeof a == 'number' ? a : 0)
+ (typeof b == 'number' ? b : 0);
Related
I need to filter my content with multiple parameters that I am taking from fields. The fields could also be empty, so I need to get all the values that are not empty. And filter by those.
What is the best way to achieve this without making a lot of if and else if conditions like this:
if (a !== '' && b !== '' && c !== '' && d !== '' && e !== ''){
// none is empty, filter by a & b & c & d & e
}
else if ( b !== '' && c !== '' && d !== '' && e !== ''){
// a is empty, filter by b & c & d & e
}
else if ( a !== '' && c !== '' && d !== '' && e !== ''){
// b is empty, filter by a & c & d & e
}
else if ( b !== '' && a !== '' && d !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && a !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && d !== '' && a !== ''){
}
else if ( c !== '' && d !== '' && e !== ''){
}
else if ( b !== '' && d !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && d !== ''){
}
else if ( a !== '' && d !== '' && e !== ''){
}
and so on...
Alternatively, how can I get all the unique possible combination of these 5 letters?
Edit ::
The actual code would look something like this
//a/b/c take value of dropdown items, that match with data on an object
if (a != '' && b != '' && c != '') {
for (const i in ParticipationList.TaskMetadata) {
if (ParticipationList.TaskMetadata[i].attendance == a && ParticipationList.TaskMetadata[i].monitoring_status == b && ParticipationList.TaskMetadata[i].monitoring_status == c) {
filteredaudience[i] = { ['id']: i }
}
console.log(filteredaudience)
// get all the items that match with the object properties
}
}
So if a or b or c is empty, I can't still make the same call, as it would not match anything on the object.
The logic:
Since javascript has short-circuit evaluation, we'll just use a bunch of conditions in the format:
field === "" || (condition to filter using field)
Because of said "short-circuiting", the right side part will only be reached if the field is not empty (i.e. if the left side is false because field !== ""). However, if the field is empty then field === "" will be true and the right side part won't be reached and the whole condition will yield true resulting in the filtering for this field to be skipped.
Multiple conditions should be joined together by the logical && operator and each one of those conditions should be wrapped in parenthesis () because the operator && is higher in precedence than the || operator.
If the data to filter is an array:
For arrays, just use the conditions as the value returned from the callback of filter like so:
let filteredData = data.filter(item =>
(a === "" || (condition for field 'a' against 'item'))
&&
(b === "" || (condition for field 'b' against 'item'))
&&
(c === "" || (condition for field 'c' against 'item'))
&&
(d === "" || (condition for field 'd' against 'item'))
&&
(e === "" || (condition for field 'e' against 'item'))
);
If the data to filter is an object:
In case the data is an object and you can't use filter like above, you can still use the same logic, you just have to use the conditions inside if like so:
let filteredaudience = {};
for (const i in ParticipationList.TaskMetadata) {
if ((a === "" || ParticipationList.TaskMetadata[i].attendance === a)
&& (b === "" || ParticipationList.TaskMetadata[i].monitoring_status === b)
&& (c === "" || ParticipationList.TaskMetadata[i].monitoring_status === c)
&& (d === "" || ParticipationList.TaskMetadata[i].?????????? === d)
&& (e === "" || ParticipationList.TaskMetadata[i].?????????? === e)) {
filteredaudience[i] = { id: i };
}
}
Depending on how the actual filtering process works, it might be possible to incrementally filter your result instead of doing it simultaneously.
For example, if your data is an array, you might write:
let data = ...;
if (a != '') {
data = data.filter(elem => checkForA(a, elem));
}
if (b != '') {
data = data.filter(elem => checkForB(b, elem));
}
...
Maybe you can also incrementally augment the filter object itself and THEN apply the built filter.
Please enter more details ...
For now, what I understood was that you want to get all the
values that are not empty.
for this:
let allElements = [a, b, c, d, e]
let notEmpty = []
allElements.forEach(element => {
if (element !== '')
notEmpty.push(element)
});
console.log(notEmpty)
A common mistake for new developers is to create long, complicated and repetative if statements with tons of && and || symbols or long strings of if/else if
Instead of this, write a simple search predicate. This is a function which takes some parameters, and reduces them to either true or false.
Within said function, run each filter one at a time. As soon as one fails, return false.
var data = [
{ colour : "red", weight : 2, name : "Example 1"},
{ colour : "orange", weight : 15, name : "Example 2"},
{ colour : "yellow", weight : 10, name : "Test 1"},
{ colour : "green", weight : 24, name : "Test 2"}
];
console.log(search(data, "red", [], ""));
console.log(search(data, "", [5,20], ""));
console.log(search(data, "", [], "Test"));
function search(data, colour, weights, name) {
return data.filter(row=>testRow(colour, weights, name, row));
}
// much easier to read.
function testRow(colourFilter, weightFilter, nameSearchFilter, row) {
// run each filter one at a time. If any fail, "short circuit" out.
if (colourFilter != "" && row.colour == colourFilter) {
return false;
}
// sometimes, a double if statemnt is easier to read.
if (weightFilter.length > 0) {
if (row.weight < weightFilter[0] || row.weight > weightFilter[1]) {
return false;
}
}
// sometimes, the actual rule is a bit complex.
if (nameSearchFilter != "") {
if (row.name.indexOf(nameSearchFilter) < 0) {
return false;
}
}
// we survived all filters.
return true;
}
I have an boolean expression in javascript and i don't know what it means.
a = (b === LEFT && -2 || b === RIGHT && 2 || 0)
Please what does it mean ?
The && is a hacky shortcut if:
if (B === LEFT) {
a = -2;
} else if (B === RIGHT) {
a = 2;
} else {
a = 0;
}
one more shortcut with ternary operator
a = b === LEFT? -2: (b === RIGHT? 2 : 0)
I am trying to alert "yes" if ether of the conditions in my if statement are true:
var a = 2;
var b = 1;
if (a = 1 or b = 1 ) {
alert('yes');// should alert in this case
} else {
alert('no');
}
https://jsfiddle.net/90z7urvd/1/
What do I use for the if, if this is possible?
a = 1 will set the value 1 to variable a. It is not doing a comparison. For comparison, you use === or ==
=== (Identity operator) is the correct way to compare if both the types are same.
if (a === 1 || b === 1 ) {
=== operator won't do the type conversion before the comparison while == does the type conversion before the comparison.
For your or case, You may use || operator
var bootresul = someExpression || anotherExpression
Corrected code
var a = 2;
var b = 1;
if (a === 1 || b === 1 ) {
alert('yes');
} else {
alert('no');
}
You are assiging value rather then comparing
Try like this
if (a == 1 || b == 1)
To compare strictly use ===
Like this
if (a === 1 || b === 1)
JSFIDDLE
you can do this
var a = 2;
var b = 1;
if ((a == 1) || (b == 1 )) {
alert('yes');// should alert in this case
} else {
alert('no');
}
the == is one of the relational operator for checking equality and || is a logical operator that is a notion of logical OR
use this to compare just values
if (a == 1 || b == 1){
}
OR use this to compare values and type of variable
if (a === 1 || b === 1){
}
note : == will just check of values and === this will check value with type of variable
var a = 2;
var b = 1;
if (a == 1 || b == 1 ) {
alert('yes');// should alert in this case
} else {
alert('no');
}
I think you were doing assignment instead of comparison
Try using this:
if(a === 1 || b === 1){
alert('YES!')
}else{
alert('NO!')
}
OR you can use ternary operator condition instead of if else
(a == 1 || b == 1) ? alert('YES!') : alert('NO!')
Help me please, I'm trying to make a rule for the little game and there is the problem.
I'm creating winning combination and say if the cell && cell+1 && cell+2 == to 'X' then you win, but when between two "X"s presents "o" it also says that "X" wins. Why? Please see my code and the game example on link a the bottom.
this.rezult = function(){
this.arr2.forEach(function(arr, i, innerArr){
arr.forEach(function(val, j){
var wincomb = innerArr[i][j] && innerArr[i][j+1] && innerArr[i][j+2];
var wincomb2 = innerArr[i][j] && innerArr[i+1][j] && innerArr[i+2][j];
var wincomb3 = innerArr[i][j] && innerArr[i+1][j+1] && innerArr[i+2][j+2];
console.log(wincomb == "X" && innerArr[i][j] !== "o");
// console.log(innerArr);
// THE RULE
if(wincomb == "X"){
alert(' X wins!');
}
});
});
};
Link to JSFiddle
In JavaScript, the && operator has interesting behavior with non-boolean values.
If the left-side of && is "truthy", the result is the right-side.
If the left-side of && is "falsey", the result is the left-side.
All non-empty strings are "truthy".
So, consider these examples:
("A" && "B" && "C") === "C"
("" && "B" && "C") === ""
(0 && "B" && "C") === 0
("X" && "X" && "O") === "O"
("O" && "O" && "X") === "X"
By the looks of it, you're trying to check if all 3 values are equal. You shouldn't use && for that, you should use === for that.
At the risk of doing your homework for you ;) here's a good way to do this:
function areTheSame(a,b,c) {
return a === b && b === c;
}
var down = areTheSame(innerArr[i][j], innerArr[i][j+1], innerArr[i][j+2]);
var across = areTheSame(innerArr[i][j], innerArr[i+1][j], innerArr[i+2][j]);
var diagonal = areTheSame(innerArr[i][j], innerArr[i+1][j+1], innerArr[i+2][j+2]);
if (down || across || diagonal) {
var winner = innerArr[i][j];
alert( winner + " wins!");
}
I put everything in parentheses but code below still throws error in jslint:
Problem at line 5 character 104: The '&&' subexpression should be wrapped in parens.
if ((typeof (c1) === 'string') && (typeof (c2) === 'string') && (c1 !== n...
How to fix ?
"use strict";
function t() {
var c1, c2;
if (((typeof (c1)) === 'string') && ((typeof (c2)) === 'string') && (c1 !== null) && (c2 !== null) && ((c1.trim()) === '') || ((c2.trim()) !== '')) {
return;
}
}
It's complaining about the form if(a && b && c || d) because (I suppose) it's not immediately obvious whether && or || will take precedence. Fix it to look like if(a && b && (c || d)) and it will stop complaining.
I think it wants this:
if (((typeof (c1) === 'string') && (typeof (c2) === 'string') && (c1 !== null) && (c2 !== null)) && ((c1.trim()) === '') || ((c2.trim()) !== '')) {
wrap the 4 anded expressions on the left of the && at 100.
I'm fairly certain you want the following:
function t() {
var c1, c2;
if (typeof c1 === 'string' && typeof c2 === 'string' && c1 !== null && c2 !== null && (c1.trim() === '' || c2.trim() !== '')) {
return;
}
}
Not everyone knows the precedence for boolean logic, so they want you to wrap the c1.trim() || c2.trim() statements in parenthesis so it's clear how they get operated.
As a side note, I think it's ridiculous that jslint wants spaces between my operators and my operands. I think it's much more clear when there is NOT a space.