I have a simple bit of code that checks some conditions, and I want each condition to cause a unique output, but if no conditions are met then to cause another unique output.
Is there any way to create an else
that is only triggered if all previous if
statements fail? I am aware that the below code carries out the same purpose, but it seems cumbersome and it would be nicer to have a quicker way of checking all of the variables than copy and paste all of them into another if statement.
var boolean1 = true,
boolean2 = true,
boolean3 = false;
if (boolean1) {
alert("boolean1");
}
if (boolean2) {
alert("boolean2");
}
if (boolean3) {
alert("boolean3");
}
/* and so on */
if (!boolean1 && !boolean2 && !boolean3 /* etc */ ) {
alert("none");
}
I have a simple bit of code that checks some conditions, and I want each condition to cause a unique output, but if no conditions are met then to cause another unique output.
Is there any way to create an else
that is only triggered if all previous if
statements fail? I am aware that the below code carries out the same purpose, but it seems cumbersome and it would be nicer to have a quicker way of checking all of the variables than copy and paste all of them into another if statement.
var boolean1 = true,
boolean2 = true,
boolean3 = false;
if (boolean1) {
alert("boolean1");
}
if (boolean2) {
alert("boolean2");
}
if (boolean3) {
alert("boolean3");
}
/* and so on */
if (!boolean1 && !boolean2 && !boolean3 /* etc */ ) {
alert("none");
}
Share
Improve this question
edited Jan 19, 2017 at 9:00
Philip Eagles
asked Jan 18, 2017 at 18:32
Philip EaglesPhilip Eagles
9481 gold badge9 silver badges27 bronze badges
7
-
3
switch
with adefault
. See switch. – zero298 Commented Jan 18, 2017 at 18:34 - 2 it would potentially be easier, if the booleans would be in an array, is that possible? – Nils Commented Jan 18, 2017 at 18:35
-
1
@zero298 — No: looks for the first case clause whose expression evaluates to the same value as the result of the input expression. If
boolean1
is true, it won't check theboolean2
case. – Quentin Commented Jan 18, 2017 at 18:39 - @zero298 My understanding is switch case evaluates based on the oute of one expression. This one deals with many Boolean variables, is that possible with switch case? – Thangadurai Commented Jan 18, 2017 at 18:41
- the accepted answer here gives a shortcut to this problem stackoverflow./questions/3463833/… – Thangadurai Commented Jan 18, 2017 at 18:45
12 Answers
Reset to default 1To make this scale, you will need to change your data structure to something you can iterate over. That way your processing logic remains the same and you can supply any size input. Here's one implementation where I use an object with properties representation your Boolean values. The checkResults
function below iterates over the property names in the object, checks the value for each one, and performs an alert and sets a flag if any value is true
. At the end it checks if any value was true
and alerts with that case.
function checkResults(resultMap) {
var any = false;
Object.keys(resultMap).forEach(function(key) {
if (resultMap[key] === true) {
any = true;
alert(key);
}
});
if (!any)
alert('none');
}
checkResults({
'boolean1': false,
'boolean2': true,
'boolean3': false
});
You can build your input object property by property if you have to:
var results = {};
results['boolean1'] = true;
results['boolean2'] = false;
...
checkResults(results);
And the checkResults
function always stays the same.
The only other way I can see to do this is for each function to set a different boolean and then test that.
var boolean1 = true,
boolean2 = true,
boolean3 = false,
any = false;
if (boolean1) {
alert("boolean1");
any = true;
}
if (boolean2) {
alert("boolean2");
any = true;
}
if (boolean3) {
alert("boolean3");
any = true;
}
/* and so on */
if (!any) {
alert("none")
}
This probably isn't much of an improvement though.
You could reduce the array of entries and return either the result of the former iteration if the boolean value is false
or true
in the other case. Finally check the returned value and show a message.
function checkResults(results) {
const
check = results => Object
.entries(results)
.reduce((r, [k, v]) => {
if (!v) return r;
console.log(k);
return true;
}, false);
if (!check(results)) console.log('none');
}
checkResults({ boolean1: false, boolean2: true, boolean3: true });
checkResults({ boolean1: false, boolean2: false, boolean3: false });
You could maintain a flag which when passes the condition alerts none
var boolean1 = true;
var boolean2 = true;
var boolean3 = false;
var allConditionFailed = true;
if (boolean1) {
alert("boolean1");
allConditionFailed = false;
}
if (boolean2) {
alert("boolean2");
allConditionFailed = false;
}
if (boolean3) {
alert("boolean3");
allConditionFailed = false;
}
if(allConditionFailed) {
alert("none");
}
var accumulated = false;
acumulated = acumulated || boolean1;
if (boolean1) {
alert("boolean1");
}
acumulated = acumulated || boolean2;
if (boolean2) {
alert("boolean2");
}
acumulated = acumulated || boolean3;
if (boolean3) {
alert("boolean3");
}
if(!acumulated) {
alert("none");
}
No, there is none. Just imagine the control flow diagram for your code, there's no way to convert that to a structured program (or even an unstructured one) without evaluating a boolean in multiple places or without introducing helper variables.
If you want to check every condition only once (in the execution I mean, not in the code), you could do
if (boolean1) {
alert("boolean1");
if (boolean2) {
alert("boolean2");
}
if (boolean3) {
alert("boolean3");
}
} else {
if (boolean2) {
alert("boolean2");
if (boolean3) {
alert("boolean3");
}
} else {
if (boolean3) {
alert("boolean3");
} else {
alert("none")
}
}
}
but that is arguably much uglier than your original solution.
I suspect what you actually want is an array of options:
var booleans = [true, true, false];
var alerts = ["boolean1", "boolean2", "boolean3"];
for (var i=0; i<booleans.length; i++)
if (booleans[i])
alert(alerts[i]);
if (booleans.every(b => !b))
alert("none");
If you can save them as an array then you can use array.indexOf()
to make sure that true doesn't exist in the array (all tests fail), and if it does loop through the array with array.forEach()
to do something with each of them.
So your code will look something like this:
// The array of conditions.
var bools = [true, true, false];
// Check if none of them are true (all fail).
if (bools.indexOf(true) === -1) {
alert("none");
} else {
// Loop over them and do something based if the current one is true.
bools.forEach(function(b, i) {
b ? alert("boolean" + (i + 1)) : '';
});
};
if an array is possible try this:
var booleans = [false, false, false];
var i = 0;
while (i < booleans.length) {
if (booleans[i] === true) {
alert("boolean"+i);
}
i++;
}
i = 0;
while (booleans[i] === false && i < booleans.length) {
i++;
}
if (i == booleans.length) {
alert('none');
}
// Filter would work like this:
var bools = booleans.filter(function (val, ind) { return !val; });
if (bools.length > 0) alert('none');
You can read more about filter() here: https://msdn.microsoft./de-de/library/ff679973(v=vs.94).aspx
Other possibilities are using .every() as @Bergi mentioned.
var boolean1 = true,
boolean2 = true,
boolean3 = false;
if(boolean1 || boolean2 || boolean3) {
if (boolean1) {
alert("boolean1");
}
if (boolean2) {
alert("boolean2");
}
if (boolean3) {
alert("boolean3");
}
} else {
alert("none");
}
When all booleans are false
, it checks only one condition and runs the else
part directly. If true
, it checks four if
-conditions, that are also checked on starting, so it is the better one.
you can use this alternative approach
var boolean1 = true,
boolean2 = true,
boolean3 = false;
let anyConditionMet = false;
if (boolean1) {
alert("boolean1");
anyConditionMet = true;
}
if (boolean2) {
alert("boolean2");
anyConditionMet = true;
}
if (boolean3) {
alert("boolean3");
anyConditionMet = true;
}
if (!anyConditionMet) {
alert("none");
}
This is not super readable but this would work:
var boolean1 = true,
boolean2 = true,
boolean3 = false;
[(boolean1 && !alert("boolean1")),
(boolean2 && !alert("boolean2")),
(boolean3 && !alert("boolean3"))]
.some(function(passed) {
return passed;
}) || alert("none");
you can use a for loop to reduce the size of the code.
var boolean1 = true,
boolean2 = true,
boolean3 = false;
none=true;
for(i=1;i<4;i++){
var variable=window["boolean"+i];
if (variable) {
alert("boolean"+i);
none=false;
}
}
if (none) {
alert("none");
}