У меня есть очень длинное условное утверждение, подобное следующему:
if(test.type == 'itema' || test.type == 'itemb' || test.type == 'itemc' || test.type == 'itemd'){
// do something.
}
Мне было интересно, смогу ли я переформулировать это выражение / утверждение в более сжатую форму.
Есть идеи, как этого добиться?
javascript
if-statement
FlyingCat
источник
источник
in
?||
. (2)switch
заявления. (3) регулярное выражение. (4)~
. jsperf.com/if-statements-test-techsinОтветы:
Поместите ваши значения в массив и проверьте, находится ли ваш элемент в массиве:
Если браузер, который вы поддерживаете, не имеет
Array#includes
метода, вы можете использовать этот polyfill .Краткое объяснение
~
ярлыка тильды:Вместо проверки, если результат
indexOf
есть>= 0
, есть хороший маленький ярлык:Вот скрипка: http://jsfiddle.net/HYJvK/
Как это работает? Если элемент найден в массиве,
indexOf
возвращает его индекс. Если предмет не был найден, он вернется-1
. Не вдаваясь в подробности,~
это побитовый оператор НЕ , который вернет0
только для-1
.Мне нравится использовать
~
ярлык, поскольку он более лаконичен, чем сравнение возвращаемого значения. Хотелось бы, чтобы в JavaScript былаin_array
функция, которая возвращала бы логическое значение напрямую (аналогично PHP), но это просто желаемое за действительное ( Обновление: теперь это происходит. Это называетсяincludes
. Смотрите выше) Обратите внимание, что jQueryinArray
, разделяя сигнатуру метода PHP, фактически имитирует нативнуюindexOf
функциональность (которая полезна в разных случаях, если индекс - это то, что вам действительно нужно).Важное примечание: использование ярлыка тильды, похоже, обернулось спорами, как некоторые яростно полагают, что код недостаточно ясен и его следует избегать любой ценой (см. Комментарии к этому ответу). Если вы разделяете их мнение, вы должны придерживаться
.indexOf(...) >= 0
решения.Немного более длинное объяснение:
Целые числа в JavaScript подписаны, что означает, что самый левый бит зарезервирован как бит знака; флаг, чтобы указать, является ли число положительным или отрицательным, с
1
отрицательным.Вот некоторые примеры положительных чисел в 32-битном двоичном формате:
Теперь вот те самые цифры, но отрицательные:
Почему такие странные комбинации для отрицательных чисел? Просто. Отрицательное число - это просто инверсия положительного числа + 1; добавление отрицательного числа к положительному числу должно всегда давать
0
.Чтобы понять это, давайте сделаем простую двоичную арифметику.
Вот как мы могли бы добавить
-1
к+1
:А вот как мы могли бы добавить
-15
к+15
:Как мы получаем эти результаты? Выполняя регулярное сложение, как нас учили в школе: вы начинаете с самого правого столбца и складываете все строки. Если сумма больше наибольшего однозначного числа (которое в десятичном виде
9
, но в двоичном1
), мы переносим остаток в следующий столбец.Теперь, как вы заметите, при добавлении отрицательного числа к его положительному номеру, самый правый столбец, который не является всем
0
s, всегда будет иметь два1
s, которые при сложении вместе приведут к2
. Двоичное представление двух существ10
, мы переносим в1
следующий столбец и помещаем0
результат в первый столбец. Все остальные столбцы слева имеют только одну строку с символом «a»1
, поэтому перенос1
из предыдущего столбца будет снова складываться2
, что затем будет перенесено ... Этот процесс повторяется до тех пор, пока мы не доберемся до самого левого столбца, где «1
Переносить» некуда, поэтому он переполняется и теряется, и мы остаемся со0
всеми.Эта система называется дополнением 2 . Вы можете прочитать больше об этом здесь:
Представление дополнения 2 для подписанных целых чисел .
Теперь, когда ускоренный курс в дополнении 2 закончен, вы заметите, что
-1
это единственное число, двоичное представление которого1
повсюду.Используя
~
побитовый оператор NOT, все биты в данном номере инвертируются. Единственный способ0
вернуться от инвертирования всех битов, если мы начали с1
все сначала.Итак, все это было многословным способом сказать, что
~n
вернется, только0
еслиn
есть-1
.источник
!== -1
каким-либо мыслимым способом? Разве явная булева логика не является более подходящей, чем неявное использование фальши нуля?!= -1
.Вы можете использовать оператор switch с fall thru:
источник
||
) в Chrome. См. Jsperf.com/if-statements-test-techsinИспользуя науку: вы должны делать то, что сказал idfah, и это для максимальной скорости, в то время как код должен быть коротким:
Это быстрее, чем
~
методhttp://jsperf.com/if-statements-test-techsin (Верхний набор: Chrome, нижний набор: Firefox)
Вывод :
Если возможности мало , и вы знаете , что некоторые из них являются более вероятны , чем вы получаете максимальную производительность из
if ||
,switch fall through
иif(obj[keyval])
.Если возможностей много , и любой из них может быть самым распространенным, другими словами, вы не можете знать, какой из них наиболее вероятен, чем вы получаете наибольшую производительность из поиска объектов
if(obj[keyval])
иregex
соответствует ли он.http://jsperf.com/if-statements-test-techsin/12
Я буду обновлять, если что-то новое появится.
источник
switch case
самый быстрый способ?if ( ...||...||...)...
obj["itemX"]
очень быстро, если n большое. В основном то, что быстро, зависит от контекста. Радоваться, веселиться.Если вы сравниваете со строками и существует шаблон, рассмотрите возможность использования регулярных выражений.
В противном случае, я подозреваю, что попытка сократить его просто запутает ваш код. Попробуйте просто обернуть строки, чтобы сделать его красивым.
источник
(test.type == 'itemf' && foo.mode == 'detailed')
)Использование объекта в качестве ассоциативного массива - довольно распространенная вещь, но, поскольку у JavaScript нет собственного набора, вы также можете использовать объекты в качестве дешевых наборов.
источник
if
выражение оператора @dcarson принимает 78 символов, если вы удалите все пробелы. Шахта занимает 54 , если вы пишете так:test.type in {"itema":1,"itemb":1,"itemc":1,"itemd":1}
. По сути, он использует четыре символа для каждых двух моих использования для каждого дополнительного ключа.или если предметы не одинаковы, то:
источник
Отличные ответы, но вы можете сделать код гораздо более читабельным, поместив один из них в функцию.
Это сложный оператор if, когда вы (или кто-то еще) прочитали код в течение нескольких лет, вы будете просматривать этот раздел, чтобы понять, что происходит. Заявление с таким уровнем бизнес-логики заставит вас запнуться на несколько секунд, пока вы решаете, что тестируете. Где, как этот код, позволит вам продолжить сканирование.
Назовите вашу функцию в явном виде, чтобы сразу было понятно, что вы тестируете, и ваш код будет намного легче сканировать и понимать.
источник
// CheckIfBusinessRuleIsTrue
?Вы можете поместить все ответы в набор Javascript, а затем просто вызвать
.contains()
его.Вы все равно должны объявить все содержимое, но встроенный вызов будет короче.
Что-то вроде:
источник
Один из моих любимых способов сделать это с помощью библиотеки, например underscore.js ...
http://underscorejs.org/#some
источник
contains
возможно лучшее решение, чемsome
some
это функция прототипа Array в EC5.другой путь или другой удивительный способ, который я нашел, это ...
конечно, как вы можете видеть, это делает вещи на шаг впереди и облегчает их следование логике.
http://snook.ca/archives/javascript/testing_for_a_v
используя операторы, такие как ~ && || ((), ()) ~~ хорошо, только если ваш код сломается позже. Вы не будете знать, с чего начать. Так что читабельность БОЛЬШАЯ.
если вам нужно, вы можете сделать его короче.
и если вы хотите сделать обратное
источник
Просто используйте
switch
утверждение вместоif
утверждения:Switch
также работает быстрее, чем сравнение множества условий вif
источник
Для очень длинных списков строк эта идея сохранит несколько символов (не говоря уже о том, что я бы порекомендовал его в реальной жизни, но он должен работать).
Выберите символ, который, как вы знаете, не встречается в вашем test.type, используйте его в качестве разделителя, вставьте их в одну длинную строку и найдите:
Если ваши строки окажутся более жесткими, вы можете даже опустить разделители ...
... но вы должны быть осторожны с ложными срабатываниями в этом случае (например, "embite" будет соответствовать в этой версии)
источник
Для удобства чтения создайте функцию для теста (да, функцию из одной строки):
тогда назовите это:
источник
Я думаю, что есть 2 цели при написании этого условия.
Таким образом, иногда # 1 может быть самым быстрым, но я возьму № 2 для удобства обслуживания позже. В зависимости от сценария я часто выбираю вариант ответа Уолтера.
Для начала у меня есть глобально доступная функция как часть моей существующей библиотеки.
и затем, когда я действительно хочу выполнить условие if, подобное вашему, я бы создал объект со списком допустимых значений:
Это не так быстро, как оператор switch / case, и немного более многословно, чем некоторые другие примеры, но я часто получаю повторное использование объекта в другом месте кода, что может быть очень удобно.
В сочетании с одним из образцов jsperf, сделанных выше, я добавил этот тест и вариацию для сравнения скоростей. http://jsperf.com/if-statements-test-techsin/6 Самое интересное, что я заметил, это то, что некоторые тестовые комбинации в Firefox выполняются намного быстрее, чем даже Chrome.
источник
Это можно решить с помощью простого цикла:
Мы используем первый раздел цикла for, чтобы инициализировать аргументы, которые вы хотите сопоставить, второй раздел, чтобы остановить цикл for, и третий раздел, чтобы в конечном итоге завершить цикл.
источник