2014-10-17 3 views
3

В недавнем разговоре с младшими разработчиками JavaScript я упомянул следующую технику вырубки трудоемким, если/иначе блоки, где OR операнд используется:Является ли это неправильным шаблоном регулярного выражения?

if (/^(cat|dog|horse)$/.test(animal)) { ... } 

вместо

if (animal == 'cat' || animal == 'dog' || animal == 'horse') { ... } 

я никогда была проблема с этим, но один человек предположил, что это плохая модель дизайна, не уточняя почему.

+0

Я думаю, что регулярное выражение в этом случае совершенно очевидно, а не как регулярное выражение, которое предлагается в большинстве вопросов в теге regex на SO. – nhahtdh

+1

Я не знаю, является ли JS против этого, но на других языках я бы создал сборку inline и посмотрел, есть ли там значение. –

+1

Не думаю, что я зашел так далеко, чтобы назвать этот «шаблон дизайна». –

ответ

1

Построение регулярного выражения является более дорогостоящим, чем выполнение нескольких сравнений строк, но если это делает код более четким, а производительность не влияет (через профилирование, конечно!), То я думаю, что все в порядке.

+0

Спасибо. Re: дорогой, я бы подумал, что это было пренебрежимо мало для сравнения этой маленькой природы, но я понимаю. – Utkanos

2

Путь регулярного выражения, несомненно, я предпочел бы в этом случае скорее поблагодарить за длинный список сравнений. Производительность также я думаю, что регулярное выражение не будет сильно уступать множественным сравнениям (представьте себе случай сравнения 30-40 для вашего животного).

Regex также дает вам другие преимущества, такие как проверка совпадения в случае игнорирования или сравнение со словом границы (для этого случая, когда ввод является частью некоторого текста), тогда как для сравнения строк потребуется дополнительный код.

+2

Вы довольно подкрепляете мои мысли о том, почему мне нравится этот шаблон. Благодарю. – Utkanos

+1

Для справки о производительности дерьмовый тест http://jsperf.com/is-this-a-bad-design-pattern. +1 к этому ответу, хотя – PeeHaa

+0

@PeeHaa: Я думаю, вы можете сделать ответ из своего теста. – nhahtdh

0

Это мнение основано, но некоторые моменты поднять являются:

код должен быть доступен для чтения, а не nessesarly коротка.

Regex более подвержен ошибкам, к примеру: если один забыл $ это будет соответствовать horses

Без документов кто-то читает код рефакторинг коду не может быть больными это назначение:

  • Если это дифференцировать животное? ^cat|dog|horse$
  • Должно ли оно отличаться от количества животных? ^cat|dog|horse

Добавление большего количества вариантов может быть проблематичным, а именно:

if (animal == 'cat' || animal == 'dog' || animal == someUserInputtedAnimal) 

Решение:

Для многих, если операторы используют переключатель или "истинный" переключатель:

switch (animal) 
{ 
    case 'cat': 
     break; 
    case 'dog': 
     break; 
    case 'horse': 
     break; 
} 

switch (true) 
{ 
    case animal == 'cat': 
     break; 
    case animal == 'dog': 
     break; 
    case animal == 'horse': 
     break; 
    case someRandomAnimal == ressurected: 

     break; 
} 
+1

Спасибо. Очевидно, я знаю о операторах switch, но дело в том, чтобы попытаться ограничить трудоемкие сравнения с более коротким кодом. Переключатель не короче. – Utkanos

+0

Пункт здесь более читаемый код, не короче. Долго, если не читаем, на мой взгляд. –

+4

Для случая использования OPs я бы очень использовал шаблон регулярного выражения вместо длинного списка оператора switch – PeeHaa

4

Мне кажется, что я пытаюсь быть слишком умным, и, тем самым, вы несколько новых потенциальных точек сбоев (в синтаксисе регулярных выражений) и сделали код менее выразительным/идиоматичным. Вы также будете бороться, если ваши операнды должны были быть от 'cat' до динамического или переменного в некотором роде.

Как правило, в этом что-то вроде этого, я только так далеко, как введение массива:

if (['cat', 'dog', 'horse'].indexOf(animal) != -1) { ... } 

Честно говоря, хотя, это все смехотворно субъективно, так что не «правильный» ответ, который я могу дать вам ,

Обычно в этот момент я бы представил проблемы с производительностью, но на самом деле у вас может быть более быстрое решение из-за необходимости сканирования ввода только один раз. Это будет зависеть от того, насколько быстро можно проанализировать регулярное выражение.

+0

Да, это один из тех вопросов на SO, где, несмотря на то, что он основан на мнениях, это, вероятно, хороший вопрос. Я думаю, что SO еще предстоит найти правильный баланс в вопросах, основанных на мнениях; это технически не то, что они хотят, но здесь есть грузы и грузы, и многие из них тоже есть. – Utkanos

+0

@Utkanos: Вот почему я ответил, а не закрыл его. –

+2

Кстати, «у них много аргументов» устал и не хватает заслуг: массы невежественны. –

Смежные вопросы