Так уже вышло что javascript был написан за 10 дней и у него много проблем с отсутствием единого синтаксиса. Особенно меня огорчает конструкция switch...case о ней и пойдёт речь ниже.
Часто возникает потребность выбрать из нескольких значений и в js для этого приходится писать нечто ужасающее:
Какие собственно недостатки?
Во-первых, не хочется после каждого варианта писать break, иначе будут выполнены все действия, которые описаны после совпавшего варианта при сравнении. Мне это напоминает bat скрипты с архаичными безусловными GOTO переходами.
Во-вторых, хотелось бы что бы можно было работать с объектами, массивами, функциями и самое главное — регулярными выражениями. И что бы это всё было ближе к функциональному, а не процедурному программированию.
Идея вынашивалась давно, годных вариантов ранее я не встречал и поэтому решил написать миниатюрную функцию, которая делала бы всё что я от неё хочу. Вот она:
cases — это хеш-массив значений, среди которых происходит поиск по переданному первому аргументу.
Если значение не найдено в cases, то будет возвращен сам аргумент, либо то что находится в cases.default
Пример:
Если передать вместо простого значения массив значений или объект(хеш-массив), то в итоге мы получим новый массив/объект в котором ключам первоначального массива/объекта соответствуют значения выбранные из cases. Проще говоря функция swtch выполняется рекурсивно для каждой пары ключ/значение. Обратите внимание — первоначальный объект не будет изменен, мы просто получим объект с таким же набором ключей.
В случае с функцией всё просто, она выполнится и к значению, которое она вернет будет применена функция swtch.
Переданное регулярное выражение будет применено методом .test() к каждому ключу cases и в тех случаях, когда оно true, значения по этим ключам будут собраны в объект, который и вернет функция.
Пример:
На изобретение велосипеда Я не претендую, это скорее тренировка мозгов для тех кто решил стать на путь js-джедая ну и просто демонстрация, на мой взгляд, изящного обхода фундаментального изъяна в популярном языке программирования.
На этом пожалуй всё.
Часто возникает потребность выбрать из нескольких значений и в js для этого приходится писать нечто ужасающее:
switch (value) {
case "value1":
doSomething()
break
case "value2":
doSomethingElse()
break
default:
orDoDefault()
}
Какие собственно недостатки?
Во-первых, не хочется после каждого варианта писать break, иначе будут выполнены все действия, которые описаны после совпавшего варианта при сравнении. Мне это напоминает bat скрипты с архаичными безусловными GOTO переходами.
Во-вторых, хотелось бы что бы можно было работать с объектами, массивами, функциями и самое главное — регулярными выражениями. И что бы это всё было ближе к функциональному, а не процедурному программированию.
Идея вынашивалась давно, годных вариантов ранее я не встречал и поэтому решил написать миниатюрную функцию, которая делала бы всё что я от неё хочу. Вот она:
function swtch(arg,cases){
return (typeof arg=='string'||typeof arg=='number')
?cases[arg]
?cases[arg]
:cases['default']||arg
:typeof arg=='object'
?(function(){
var ret=arg instanceof Array?[]:{}
,i
if(arg.constructor===RegExp)
for(i in cases)
cases.hasOwnProperty(i)&&arg.test(i)&&(ret[i]=cases[i])
else
for(i in arg)
if(arg.hasOwnProperty(i))
ret[i]=swtch(arg[i],cases)
return ret
})()
:typeof arg=='function'
?swtch(arg(),cases)
:arg
}
cases — это хеш-массив значений, среди которых происходит поиск по переданному первому аргументу.
Если значение не найдено в cases, то будет возвращен сам аргумент, либо то что находится в cases.default
Пример:
swtch('1',{
"1":'one'
,"2":'two'
}) // возвращает 'one'
swtch(2,{
"1":'one'
,"2":'two'
}) // возвращает 'two'
swtch(3,{
"1":'one'
,"2":'two'
}) // возвращает 3
swtch(3,{
"1":'one'
,"2":'two'
,default:'default value'
}) // возвращает default value
Если передать вместо простого значения массив значений или объект(хеш-массив), то в итоге мы получим новый массив/объект в котором ключам первоначального массива/объекта соответствуют значения выбранные из cases. Проще говоря функция swtch выполняется рекурсивно для каждой пары ключ/значение. Обратите внимание — первоначальный объект не будет изменен, мы просто получим объект с таким же набором ключей.
swtch([1,2],{
"1":'one'
,"2":'two'
}) // возвращает ['one','two']
swtch({a:1,b:2},{
"1":'one'
,"2":'two'
}) // возвращает {a:'one',b:'two'}
В случае с функцией всё просто, она выполнится и к значению, которое она вернет будет применена функция swtch.
Переданное регулярное выражение будет применено методом .test() к каждому ключу cases и в тех случаях, когда оно true, значения по этим ключам будут собраны в объект, который и вернет функция.
Пример:
swtch(/\d/,{
"1":'one'
,"2":'two'
,"foo":'first string'
,"bar":'second string'
}) // возвращает {"1":'one',"2":'two'}
swtch(/\D/,{
"1":'one'
,"2":'two'
,"foo":'first string'
,"bar":'second string'
}) // возвращает {"foo":'first string',"bar":'second string'}
На изобретение велосипеда Я не претендую, это скорее тренировка мозгов для тех кто решил стать на путь js-джедая ну и просто демонстрация, на мой взгляд, изящного обхода фундаментального изъяна в популярном языке программирования.
На этом пожалуй всё.