умный способ выполнить блок кода, если любое условие в if / else, если было верно - PullRequest
2 голосов
/ 01 марта 2020

У меня часто бывает if / else if, где блоки частично содержат один и тот же код. Я хотел бы написать этот код только один раз, что-то вроде «not else» (блок else выполняется, если не выполнено никакое предварительное условие, блок not else будет выполнен, если выполнено какое-либо предыдущее условие). Я знаю, что вы можете установить флаг в каждом блоке и проверить, установлен ли флаг впоследствии, или создать функцию, которая вызывается в каждом блоке (если вам не нужно редактировать локальные переменные). У вас есть идея для более умного / элегантного решения? При корректировке вопроса мне пришла в голову идея вернуться в блок else и поместить после него ваш общий код - работает, только если вам не нужно возвращаться раньше.

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 */ 

}

Ответы [ 3 ]

2 голосов
/ 01 марта 2020

Нетрадиционным решением было бы все oop, которое повторяется один раз, тем самым давая вам опцию break:

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

Но для удобства чтения я бы go для опции флага, которую вы уже упоминается в вопросе.

0 голосов
/ 01 марта 2020

99 раз из 100, я буду go с тем, что предлагает Caw в своем удаленном ответе.

Но если у вас очень длинный набор условий (например, больше чем 10), вы можете рассмотреть возможность использования карты (ассоциативного массива) для поиска путей кода к условиям

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 */

Это может быть полезно, когда уникальный путь кода для каждого условия делает что-то тривиальное (например, перевод значения установка состояния синтаксического анализа, обработка токена и т. д. c ...), и общий код - это то, где находится цель функции. Обычно вышеприведенное - это то, к чему вы переходите, когда в исходной реализации слишком много условий if / else.

0 голосов
/ 01 марта 2020

Вы можете сохранить условия и их соответствующие коды в списке следующим образом:

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 */
}

Но это, вероятно, целесообразно, только если все условия дешевы. Если они стремятся к производительности, все они будут выполнены, хотя на самом деле необходимо проверить только некоторые из них. Если условия действительно дороги, вы можете использовать вызов функции вместо фактических условий и вызывать их в some l oop.

...