Оператор switch для сопоставления строк в JavaScript
Как написать swtich для следующего условного?
Если url содержит "foo", тогда settings.base_url является "bar".
Следующее - это необходимый эффект, но я чувствую, что это будет более управляемым в коммутаторе:
var doc_location = document.location.href;
var url_strip = new RegExp("http:\/\/.*\/");
var base_url = url_strip.exec(doc_location)
var base_url_string = base_url[0];
//BASE URL CASES
// LOCAL
if (base_url_string.indexOf('xxx.local') > -1) {
settings = {
"base_url" : "http://xxx.local/"
};
}
// DEV
if (base_url_string.indexOf('xxx.dev.yyy.com') > -1) {
settings = {
"base_url" : "http://xxx.dev.yyy.com/xxx/"
};
}
Ответы
Ответ 1
Вы не можете сделать это в switch
, если не выполняете полное соответствие строк; что делает подстроку. (Это не совсем так, как отмечает Шон в комментариях. См. примечание в конце.)
Если вы счастливы, что ваше регулярное выражение наверху удаляет все, что вы не хотите сравнивать в своем матче, вам не нужно подстрочное совпадение и можно было бы сделать:
switch (base_url_string) {
case "xxx.local":
// Blah
break;
case "xxx.dev.yyy.com":
// Blah
break;
}
... но опять же, это работает только в том случае, если полная строка соответствует. Это не сработает, если base_url_string
были, скажем, "yyy.xxx.local", тогда как ваш текущий код будет соответствовать этому в ветке "xxx.local".
Обновить. Хорошо, так что технически вы можете использовать switch
для подстроки, но я бы не рекомендовал его в большинстве ситуаций. Вот как (живой пример):
function test(str) {
switch (true) {
case /xyz/.test(str):
display("• Matched 'xyz' test");
break;
case /test/.test(str):
display("• Matched 'test' test");
break;
case /ing/.test(str):
display("• Matched 'ing' test");
break;
default:
display("• Didn't match any test");
break;
}
}
Это работает из-за того, как работают JavaScript switch
, в частности два ключевых аспекта: во-первых, что случаи рассматриваются в источнике текстовый порядок, а во-вторых, что выражения селектора (биты после ключевого слова case
) являются выражениями, которые оцениваются по мере того, как этот случай оценивается (а не константы, как на некоторых других языках). Так как наше тестовое выражение true
, первое выражение case
, которое приводит к true
, будет тем, которое будет использоваться.
Ответ 2
RegExp может использоваться во входной строке не только технически, но и практически с помощью метода match
.
Поскольку вывод match()
является массивом, нам нужно получить первый элемент массива результата. Когда совпадение не выполняется, функция возвращает null
. Чтобы избежать ошибки исключения, мы добавим условный оператор ||
перед доступом к первому элементу массива и протестируем его с помощью свойства input
который является статическим свойством регулярных выражения, которые содержат входную строку.
str = 'XYZ test';
switch (str) {
case (str.match(/^xyz/) || {}).input:
console.log("Matched a string that starts with 'xyz'");
break;
case (str.match(/test/) || {}).input:
console.log("Matched the 'test' substring");
break;
default:
console.log("Didn't match");
break;
}
Другой подход заключается в использовании конструктора String()
для преобразования результирующего массива, который должен иметь только 1 элемент (без групп захвата), а целая строка должна быть захвачена с помощью quanitifiers (.*
) в строку. В случае сбоя объект null
станет строкой "null"
. Не удобно.
str = 'haystack';
switch (str) {
case String(str.match(/^hay.*/)):
console.log("Matched a string that starts with 'hay'");
break;
}
В любом случае более элегантным решением является использование метода /^find-this-in/.test(str)
с switch (true)
, который просто возвращает логическое значение, и его легче искать без чувствительности к регистру.
Ответ 3
Просто используйте свойство location.host
switch (location.host) {
case "xxx.local":
settings = ...
break;
case "xxx.dev.yyy.com":
settings = ...
break;
}
Ответ 4
Другой вариант - использовать поле input
в результат соответствия регулярного выражения:
str = 'XYZ test';
switch (str) {
case (str.match(/^xyz/) || {}).input:
console.log("Matched a string that starts with 'xyz'");
break;
case (str.match(/test/) || {}).input:
console.log("Matched the 'test' substring");
break;
default:
console.log("Didn't match");
break;
}
Ответ 5
var token = 'spo';
switch(token){
case ( (token.match(/spo/) )? token : undefined ) :
console.log('MATCHED')
break;;
default:
console.log('NO MATCH')
break;;
}
→ Если совпадение выполнено, тернарное выражение возвращает исходный токен
---- > Исходный токен оценивается по случаю
- > Если совпадение не выполняется, тройной возвращает undefined
---- > Дело оценивает токен против undefined, который, надеюсь, не имеет токена.
Тройной тест может быть любым, например, в вашем случае
( !!~ base_url_string.indexOf('xxx.dev.yyy.com') )? xxx.dev.yyy.com : undefined
===========================================
(token.match(/spo/) )? token : undefined )
является тройным выражением.
В этом случае тестом является токен .match(/spo/), который указывает совпадение строки, хранящейся в токене, с выражением regex/spo/(которое в данном случае является буквенной строкой).
Если выражение и строка соответствуют ему, это возвращает true и возвращает токен (который является строкой, на которой работает оператор switch).
Очевидно, токен === token, так что оператор switch согласован и оценивается случай
Легче понять, если вы посмотрите на него в слоях и поймете, что тест turnery оценивается "ПЕРЕД" командой switch, так что оператор switch видит результаты теста.
Ответ 6
Это может быть проще. Попробуйте подумать так:
- сначала поймать строку между регулярными символами
- после этого найдите "случай"
:
// 'www.dev.yyy.com'
// 'xxx.foo.pl'
var url = "xxx.foo.pl";
switch (url.match(/\..*.\./)[0]){
case ".dev.yyy." :
console.log("xxx.dev.yyy.com");break;
case ".some.":
console.log("xxx.foo.pl");break;
} //end switch