Есть ли способ сократить длинный оператор switch ()? - PullRequest
5 голосов
/ 21 сентября 2019

Я имел дело с довольно многими случаями в моих операторах switch () и задавался вопросом, есть ли какой-нибудь способ, которым я мог бы сократить их.Они занимают много места в моем коде, и с ними сложнее ориентироваться, когда есть 3-4 больших фрагмента этих утверждений.Вот пример:

...important lines of code...

void foo(string bar, bool blam) {

     int v1 = stoi(bar);

     switch (v1) {
         case(11):
             if(blam) {
                exArr[1] = "A";
             } else {
                exArr[1] = "B";
             }
             break;

         case(12):
             if(blam) {
                 exArr[3] = "A";
             } else {
                 exArr[3] = "B";
             }
             break;

         ...many more cases...

         default:
             printElement();
             break;
}
...even more important code, which is dependent on the hard code above and hard to navigate...

Я думаю, вы видите проблему.Ребята, у вас есть предложения?Заранее спасибо.

ВАЖНОЕ РЕДАКТИРОВАНИЕ:

Только первые 12 итераций изменяют символы exArr.После этого он изменяется на другой (существующий) массив, например ndArr, который занимает еще 12 итераций.Это продолжается для 4 массивов, то есть для 48 операторов case.

Ответы [ 4 ]

4 голосов
/ 21 сентября 2019

Ну, во-первых, вы можете удалить фигурные скобки в операторах if else, так как они представляют собой один вкладыш, внутри блоков case, подобных этому

...
case(12):
    if(blam)
        exArr[3] = "A";
    else
        exArr[3] = "B";
    break;
...

, и вы можете сделать еще один шаг и использовать операторы Tenary.который выглядел бы так

1006 *
4 голосов
/ 21 сентября 2019

Как отметил @Alexander Zhang, если у вас есть конкретный алгоритм, который вы можете использовать, простейшее решение вашей проблемы будет похоже на то, что предлагает @Ton van den Heuvel.

Если нет, то есть иальтернатива использования справочной таблицы (ссылка здесь здесь ), если у вас есть конкретные значения, которые совпадают.

Например.

#include <map>

.../

map<int,int> mapV1toIndex = {
    {11, 1}, 
    {12, 3},
    .../
};

void foo(string bar, bool blam) {
    int v1 = stoi(bar);
    exArr[mapV1toIndex[v1]] = (blam) ?  "A" : "B";
}

Кроме того, если вы хотите каждый раз использовать разные строковые массивы, вы можете передать массив строк в foo, например, чтобы повторно использовать функцию foo:

void foo(string *pStrArray, string bar, bool blam) {
    int v1 = stoi(bar);
    pStrArray[mapV1toIndex[v1]] = (blam) ?  "A" : "B";
}

Редактировать:Предпочтительно использовать std :: map вместо struct.Отредактировал код для использования карты, следуя этой ссылке.

1 голос
/ 21 сентября 2019

Если предположить, что соотношение между v1 и последующими случаями продолжается таким же образом, переключатель не требуется:

const int v1{stoi(bar)};
if (11 <= v1 && v1 <= ...)
  exArr[1 + (v1 - 11) * 2] = blam ? "A" : "B";
else
  printElement();
0 голосов
/ 22 сентября 2019

В идеале вы должны попытаться решить эту проблему, используя полиморфизм.Я нашел это в stackoverflow, Способы устранения переключения в коде .Пример напрямую не реализован в C ++, но даст вам представление.Благодаря полиморфизму ваш код станет намного более читабельным и легко расширяемым в будущем.

...