Как я могу использовать диапазоны в операторе switch switch, используя JavaScript?
Как использовать диапазоны в операторе case с помощью JavaScript? Поэтому, вместо написания кода для каждой возможности, я хотел бы сгруппировать их в диапазонах, например:
6 ответов
У вас есть как минимум четыре варианта:
1. Перечислите каждый case
Как показанный LightStyle, вы можете явно указать каждый случай:
2. Используйте if / else if / else
Если диапазоны большие, это становится громоздким, поэтому вы хотите делать диапазоны. Обратите внимание, что при if. else if. else if вы не дойдете до более поздних, если предыдущий соответствует, поэтому вам нужно только каждый раз указывать верхнюю границу. Я буду включать нижнюю границу в /*. */ для ясности, но обычно вы можете оставить ее, чтобы избежать введения проблемы обслуживания (если вы включаете обе границы, легко изменить ее и забыть изменить другую):
3. Используйте case с выражениями:
JavaScript необычен тем, что вы можете использовать выражения в выражении case , поэтому мы можем написать последовательность if. else if. else if выше как оператор switch :
Я не сторонник этого, но это вариант в JavaScript, и есть время, когда это полезно. Операторы case проверяются в порядке на значение, указанное в switch . (И снова, нижние границы могут быть опущены во многих случаях, потому что они бы соответствовали ранее.) Несмотря на то, что case обрабатываются в порядке исходного кода, default может отображаться в любом месте (а не только в конце) и обрабатывается только в том случае, если либо не соответствует case , либо case соответствует и падает до значения по умолчанию (не было break ; редко вы хотите это сделать, но это происходит).
4. Используйте карту отправки
Если ваши функции все принимают одни и те же аргументы (и это могут быть не аргументы или одни и те же), другой подход — это карта отправки:
В некотором установочном коде:
Затем вместо переключателя:
Это работает, просматривая функцию для вызова карты dispatcher , по умолчанию doStuffWithAllOthers , если нет записи для этого конкретного значения myInterval , используя любопытно-мощный || оператор, а затем вызывающий его.
Вы можете разбить это на две строки, чтобы сделать его более понятным:
Я использовал объект для максимальной гибкости. Вы можете определить dispatcher следующим образом:
. но если значения не являются смежными числами, гораздо проще использовать объект.
Как в case задать диапазон
How can I use ranges in a switch case statement using JavaScript? So, instead of writing code for each and every single possibility, I’d like to group them in ranges, For example:
7 Answers 7
You have at least four options:
1. List each case
As shown by LightStyle, you can list each case explicitly:
2. Use if / else if / else
If the ranges are large, that gets unwieldy, so you’d want to do ranges. Note that with if. else if. else if , you don’t get to the later ones if an earlier one matches, so you only have to specify the upper bound each time. I’ll include the lower bound in /*. */ for clarity, but normally you would leave it off to avoid introducing a maintenance issue (if you include both boundaries, it’s easy to change one and forget to change the other):
3. Use case with expressions:
JavaScript is unusual in that you can use expressions in the case statement, so we can write the if. else if. else if sequence above as a switch statement:
I’m not advocating that, but it is an option in JavaScript, and there are times it’s useful. The case statements are checked in order against the value you give in the switch . (And again, lower bounds could be omitted in many cases because they would have matched earlier.) Even though the case s are processed in source-code order, the default can appear anywhere (not just at the end) and is only processed if either no case s matched or a case matched and fell through to the default (didn’t have a break ; it’s rare you want to do that, but it happens).
4. Use a dispatch map
If your functions all take the same arguments (and that could be no arguments, or just the same ones), another approach is a dispatch map:
In some setup code:
Then instead of the switch:
That works by looking up the function to call on the dispatcher map, defaulting to doStuffWithAllOthers if there’s no entry for that specific myInterval value using the curiously-powerful || operator, and then calling it.
You can break that into two lines to make it a bit clearer:
I’ve used an object for maximum flexibility. You could define dispatcher like this with your specific example:
. but if the values aren’t contiguous numbers, it’s much clearer to use an object instead.
How do I select a range of values in a switch statement?
How can I fix this problem? It’s a console application, Win32 and my IDE is Windows Enterprise C++ 2010.
I’m learning from Beginning C++ Through Game Programming.
18 Answers 18
Some compilers support case ranges like case x . y as an extension to the C++ language.
GCC 4.9, Clang 3.5.1 and Intel C/C++ Compiler 13.0.1 seem to support it (tried on http://gcc.godbolt.org/). On the other hand, Visual C++ 19 doesn’t (tried on http://webcompiler.cloudapp.net/).
In C++ case labels are constant expressions, not expressions in general. You need a chain of if-then-else statements to do what you are trying to do.
Alternatively, you can enumerate the values in the switch. This runs marginally faster (though it does not matter in cases like yours), but it is considerably less readable:
You can fix this problem by using a series of if / else if statements. Switch/case cannot be used like this in C++.
It can be done using a std::map with switch :
![]()
Switch-case is not a great option for testing ranges. The best option is to use several if :
If running time is an issue, the following solution is faster :
![]()
There’s a GCC extension that does exactly what you want.
In C++ a switch statement can only match constant integer values:
= C++14). Although I have a feeling I read a proposal about this at some point, it seems it was rejected.
The standard does not allow for this:
6.4.2 The switch statement [stmt.switch]
[. ] Any statement within the switch statement can be labeled with one or more case labels as follows:
case constant-expression :
where the constant-expression shall be an integral constant expression (5.19).
In other words, you can only use case-values that expand into a single, integral, «hard» compile time constant (e.g. case 5+6: , enum
The way around this is to use if -statements. E.g., to replace
std::map::upper_bound + C++11 lambdas
https://stackoverflow.com/a/35460297/895245 mentioned lower_bound , but we can also get rid of the enum there with lambdas (or inheritance if you don’t have it).
Usage inside methods with static
To use this pattern efficiently inside classes, initialize the lambda map statically, or else you pay n log(n) every time to build it from scratch.
Here we can get away with the <> initialization of a static method variable: Static variables in class methods , but we could also use the methods described at: static constructors in C++? I need to initialize private static objects
It was necessary to transform the lambda context capture [&] into an argument, or that would have been undefined: const static auto lambda used with capture by reference
Как в case задать диапазон
Конструкция switch/case похожа на конструкцию if/else , так как позволяет обработать сразу несколько условий:
После ключевого слова switch идет сравниваемое выражение. Это может быть переменная или константа. Значение этого выражения последовательно сравнивается со значениями, помещенными после оператора сase . И если совпадение будет найдено, то будет выполняться определенный блок сase .
Если совпадение не будет найдено, то выполняется оператор default .
В данном случае так как переменная num равна 22, будет выполняться следующий блок case:
В других языках программирования, в которых также есть конструкция switch/case , обычно в конце блока case ставится оператор break для прерывания выполнения и выхода из блока switch/case . В Swift использовать оператор break в подобных случаях необязательно. Однако бывают случаи, когда мы не хотим обрабатывать какие-то определенные значения и просто хотим выйти из конструкции switch. В этом случае после оператора case или default можно указать оператор break:
В данном случае если num равно 10 или другому числу, отличному от 0 или 22, просто произойдет выход из switch.
С помощью знака подчеркивания _ можно задать соответствие всем остальным значениям:
Также мы можем сравнивать выражение не с одним значением, а с группой значений:
Оператор case 0, 10 задает два сравниваемых значения 0 и 10 и срабатывает, если выражение равно одному из этих значений.
Оператор case 11..<20 определяет целый диапазон значений от 11 до 20 (не включая 20) и срабатывает, если выражение равно значению из этого диапазона.
Оператор case 20. 30 определяет целый диапазон значений от 20 до 30 (включая оба числа) и срабатывает, если выражение равно значению из этого диапазона.
В версии Swift 4 мы можем опускать одну границу диапазона:
Кортежи в switch/case
Кроме выражений простых типов можно сравнивать кортежи:
Здесь кортеж personInfo последовательно сравнивается с тремя кортежами в операторах case. При сравнении мы можем задать полный кортеж:
Либо мы также можем опустить один из элементов кортежа, подставив вместо него знак подчеркивания _:
В этом случае не имеет значение, чему равен первый элемент кортежа, главное, чтобы второй элемент кортежа был равен 22.
Для числовых данных мы также можем задать не точное значение, а диапазон значений:
В этом случае второй элемент кортежа должен находиться в диапазоне от 1 до 30.
В использованной нами выше конструкции switch/case сравниваемому выражению соответствуют аж три оператора case — второй, третий и четвертый, но выполняться будет только первый из них.
Но если мы хотим, чтобы также выполнялся и следующий оператор case (или оператор default), то в конце предыдущего блока case следует использовать оператор fallthrough :
Связывание значений
Механизм связывания значений позволяет определить в блоках case переменные и константы, значения которых будут связаны со значением сравниваемого выражения:
В данном случае если значение number не равно 1 и 2, то оно передается константе n, которая используется в рамках своего блока case.
При этом привязка может выполняться к переменным и константам более сложных типов, например, кортежей:
Если второй элемент в personInfo равен 22, то срабатывает блок
Здесь переменная name получает значение первого элемента из кортежа personInfo.
Причем в этой конструкции не используется блок default , так как блок
фактически перекрывает все возможные случаи, которые не попадают под предыдущие операторы case. В этом блоке определяется константа (хотя это может быть и переменная), которая состоит из элементов кортежа personInfo.
Оператор where
Если при выполнении блока case мы хотим задать дополнительные условия, то в этом случае нам поможет оператор where . Например:
Пример с кортежами:
Выражения where определяют дополнительные условия. И если они не выполняются, то соответственно блок case тоже не выполняется.