简体   繁体   中英

clever way to execute code block if any condition in if/else if was true

I often have if/else if where the blocks partially contain the same code. I would like to only have to write this code once, something like a "not else" (the else block is executed if no prior condition is met, the not else block would be executed if any prior condition is met). I know you could set a flag in each block and test if the flag is set afterwards, or create a function which is called in each block (if you dont need to edit local variables). Do you have an idea for a more clever/elegant solution? While proofreading the question I came up with the idea to return in the else block and put your common code after it - only works if you dont have to return before though.

if (condition1) {
    /* unique code1 */
    /* common code */        

} else if (condition2) {
    /* unique code2 */
    /* common code */ 

} else if (condition3) {
    /* unique code3 */
    /* common code */ 

} else if (condition4) {
    /* unique code4 */
    /* common code */ 

}

An unconventional solution would be a loop that iterates once, thereby giving you the break option:

do {
    if (condition1) {
        // ...
    } else if (condition2) {
        // ...
    } else if (condition3) {
        // ...
    } else break;
    // common code
} while (false);

But for readability I would go for the flag-option which you already mentioned in the question.

You could store the conditions and their respective code in a list as follows:

const conditions = [
  [condition1, () => {/* unique code1 */}],
  [condition2, () => {/* unique code2 */}],
  [condition3, () => {/* unique code3 */}],
  [condition4, () => {/* unique code4 */}],
];

const hasTruthy = conditions.some(([condition, fn]) => {
  if (condition) {
    fn();
    return true;
  }
});

if (hasTruthy) {
  /* common code */
}

But that is probably only advisable if all the conditions are cheap. If they are performance-hungry, all of them would be executed even though only some are actually necessary to be checked. If the conditions are indeed expensive, you could use a function call instead of the actual conditions and call them in the some loop.

99 times out of 100, I'll go with what caw suggests in his now deleted answer.

But if you have an extremely long set of conditions (like more than 10), you could consider using a map (associative array) to lookup code paths to conditions

let action_table = [];
action_table["condition1"] = ()=>{/* unique code 1 */};
action_table["condition2"] = ()=>{/* unique code 2 */};
action_table["condition3"] = ()=>{/* unique code 3 */};
action_table["condition4"] = ()=>{/* unique code 4 */};

let condition = /*compute condition based on variables and state*/;
action_table[condition](); /* execute unique code action */
unique_code();

/* common code */

This can be useful when the unique code path for each condition is doing something trivial (like translating a value, setting a parse state, processing a token, etc...) and the common code is where the heart of the function's purpose is. Usually the above is what you switch to when the original implementation starts to have too many if/else conditions.

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