简体   繁体   中英

javascript if if else (not else if)

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"); } 

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.

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.com/de-de/library/ff679973(v=vs.94).aspx

Other possibilities are using .every() as @Bergi mentioned.

To 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.

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");
}

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 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");
}

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");

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");
}

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)) : '';
});
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM