#javascript #nested #switch-statement #conditional-statements
Вопрос:
Я должен построить условие, основанное на одном или двух значениях.
const getLabel = (type?: string, typeXy?: string) => {
let label;
switch (type || typeXy) {
case 'Value A':
label = 'Label A';
break;
case 'Value B':
label = 'Label B';
break;
case 'Value C':
case 'Value X':
label = 'Label C X';
break;
case 'Value Y':
label = 'Label C Y';
break;
default:
break;
}
return label;
};
Мне нужно дело Даббела в двух местах. Когда я добавляю case 'Value C':
выше case 'Value Y':
, я получаю:
Этикетка с дубликатом дела.eslintno-дубликат-дело
1) Я добавляю // eslint-disable-next-line no-duplicate-case
, но мой код еще не работает. Или в любом случае есть более чистый способ?
2) Я могу переключить свой переключатель с or
: на and
: (type || typeXy)
но тогда первый случай не работает? Как мне поддержать и or
то, и and
другое ?
Комментарии:
1. Когда вам нужна логическая ИЛИ (
||
) и когда вам нужна логическая И (amp;amp;)? Можете ли вы объяснить, что вы хотите, чтобы код выполнял в английских предложениях/маркированных пунктах?2. Выражение
a || b
имеет конкретное значение: «приведите к значениюa
, если оно не является ложным; еслиa
является ложным, то приведите к значениюb
«.3.В третьем случае вы имеете
type
в виду, содержит ли «Значение C» иtypeXy
содержит ли «Значение X»?4. Для первых двух случаев (случай «Значение A» и случай «Значение B») мне нужно Или (
||
), потому что мне нужно пройтиtype
туда. Для случая «Значение C» мне нужны обаtype
иtypeXy
. И то же самое для того, ниже которого следует вернуться'Label C Y'
Ответ №1:
Если я понимаю ваш вопрос, вы хотите условно проверить, передаются ли оба аргумента, и если да, используйте логическое И сравнение, в противном случае, если передается только один или другой, вернитесь к логическому ИЛИ сравнению.
Используйте внешний переключатель для ветвления на логическом И/ИЛИ условии, а затем используйте вложенные переключатели для оценки конкретных комбинаций И или ИЛИ.
const getLabel = (type /*?: string*/, typeXy /*?: string*/) => {
switch (true) {
case !!(type amp;amp; typeXy):
switch (type) {
case "Value C": {
let label = "Label C";
switch (typeXy) {
case "Value X":
return label " X";
case "Value Y":
return label " Y";
}
}
}
break;
case !!(type || typeXy):
switch (type || typeXy) {
case "Value A":
return "Label A";
case "Value B":
return "Label B";
}
}
};
console.log(getLabel("Value A")); // Label A
console.log(getLabel("Value B")); // Label B
console.log(getLabel(undefined, "Value A")); // Label A
console.log(getLabel(undefined, "Value B")); // Label B
console.log(getLabel("Value C", "Value X")); // Label C X
console.log(getLabel("Value C", "Value Y")); // Label C Y
Комментарии:
1. спасибо за ваш ответ! Это прекрасно работает. Однако вы получаете множество вложенных операторов переключения. Было бы более чистое решение, возможно, с
if/else
заявлениями в этом случае?2. @meez … в приведенном выше коде нет ничего «грязного» . Таким образом, нет ничего «чище» . Любой синтаксис, поддерживающий сложную логику (регистр переключения, если иначе, тернарные и булевы операторы), в конечном итоге будет вложен для выражения потребностей операции. Единственным ярлыком, который также может быть проще для чтения и обслуживания, может быть подход, основанный на поиске.
3. @Дрю Риз, не могли бы вы объяснить, почему вы используете
!!
здесь двойника? Просто чтобы понять.4. @Питер Селигер, что вы имеете в виду под подходом, основанным на поиске?
5. @meez Я не знаю о более чистом решении, но
switch
утверждение фактически является «синтаксическим сахаром» вокруг серии утверждений if-else-if. Функция double-bang (!!
) используется для приведения условных выражений к логическому значению дляswitch
случаев. Питер означает карту поиска/объект каждой строковой комбинации логических ИЛИ и И аргументов.
Ответ №2:
Как насчет использования объектного литерала в качестве таблицы поиска, в которой можно точно выразить, какой результат для какого случая вы предпочитаете ?..
const getLabel = (type/*?: string*/, typeXy/*?: string*/) => {
return ({
'Value A': 'Label A',
'Value B': 'Label B',
'Value C': 'Label C',
'Value X': 'Label X',
'Value Y': 'Label Y',
'Value CValue X': 'Label C X',
'Value XValue C': 'Label C X',
'Value CValue Y': 'Label C Y',
'Value YValue C': 'Label C Y',
})[(type ?? '') (typeXy ?? '')];
};
console.log("getLabel('Value A') ...", getLabel('Value A'));
console.log("getLabel('Value B', null) ...", getLabel('Value B', null));
console.log("getLabel(null, 'Value C') ...", getLabel(null, 'Value C'));
console.log("getLabel(undefined, 'Value X') ...", getLabel(undefined, 'Value X'));
console.log("getLabel('Value Y') ...", getLabel('Value Y'));
console.log("getLabel('Value C', 'Value X') ...", getLabel('Value C', 'Value X'));
console.log("getLabel('Value X', 'Value C') ...", getLabel('Value X', 'Value C'));
console.log("getLabel('Value C', 'Value Y') ...", getLabel('Value C', 'Value Y'));
console.log("getLabel('Value Y', 'Value C') ...", getLabel('Value Y', 'Value C'));
.as-console-wrapper { min-height: 100%!important; top: 0; }
Комментарии:
1. @meez … Есть ли какие-либо вопросы относительно вышеуказанного подхода?