Например, примерно так:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
Есть ли лучший способ написать это? Опять же, я не ищу ответа на точный вопрос выше, просто пример того, когда вы могли повторять операнды в выражениях тернарных операторов ...
javascript
conditional-operator
user1354934
источник
источник
if
а не anif/else
just an example of when you might have repeated things in the ternary
не повторяйте вычисленные выражения. Вот для чего нужны переменные.3
не в индексе0
изsomeArray
?Math.max(someArray.indexOf(3), 0)
вместо этого?Ответы:
Лично я считаю, что лучший способ сделать это - по-прежнему старое доброе
if
утверждение:источник
if
оператора вместо троичного. Тернарные операторы по-прежнему часто используются для выполнения выбора как части выражения.value
после первой строки, является промежуточным. Он не содержит правильного значения, которое затем фиксируется в следующей строке и, таким образом, является промежуточным. Только после того, какif
утверждениеvalue
содержит правильное значение. Тернар в OP - лучшее решение, потому что он никогда не входит в промежуточное состояние.value
здесь технически видоизменено, чего я стараюсь избегать.Код должен быть удобочитаемым, поэтому краткость не должна означать, что вы должны быть краткими независимо от стоимости - для этого вам следует сделать репост на https://codegolf.stackexchange.com/ - поэтому вместо этого я бы рекомендовал использовать вторую локальную переменную с именем,
index
чтобы максимизировать понятность чтения ( с минимальными затратами времени выполнения тоже отмечу):Но если вы действительно хотите сократить это выражение, потому что вы жестокий садист по отношению к своим коллегам или сотрудникам проекта, то вот 4 подхода, которые вы можете использовать:
1: временная переменная в
var
оператореВы можете использовать возможность
var
оператора определять (и назначать) вторую временную переменную,index
разделенную запятыми:2: Самостоятельно выполняющаяся анонимная функция
Другой вариант - самоисполняющаяся анонимная функция:
3: оператор запятой
Есть также печально известный «оператор запятой», который поддерживает JavaScript, который также присутствует в C и C ++.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
Вы можете использовать его для введения побочных эффектов, в этом случае переназначив
value
:Это работает, потому что
var value
сначала интерпретируется (как оператор), а затем самое левое, самое внутреннееvalue
присваивание, затем правая часть оператора запятой, а затем тернарный оператор - все это допустимый JavaScript.4. Переназначить в подвыражении
Комментатор @IllusiveBrian указал, что в использовании оператора-запятой (в предыдущем примере) нет необходимости, если присвоение to
value
используется в качестве подвыражения в скобках:Обратите внимание, что использование отрицательных чисел в логических выражениях может быть труднее для понимания людьми, поэтому все приведенные выше примеры можно упростить для чтения, изменив
idx !== -1 ? x : y
наidx == -1 ? y : x
:источник
indefOf
)var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
вместо использования запятой.var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
потому что это всего лишь один параметр.Для чисел
Вы можете использовать
Math.max()
функцию.Он сохранит границы результата от времени
0
до первого результата выше, чем0
в этом случае. И если результат изindexOf
is,-1
он вернет 0 как больше чем-1
.Для логических и логических значений y
Для JS нет общего правила AFAIK, особенно из-за того, как оцениваются ложные значения.
Но если что-то может вам помочь, так это оператор or (
||
):Вы должны быть очень осторожны с этим, потому что в вашем первом примере
indexOf
может возвращаться,0
и если вы оцените,0 || -1
он вернется,-1
потому что0
это ложное значение.источник
3
или"y"
не по индексу0
вsomeArray
?Math.max
примере?indexOf
возвращает индекс элемента, и если элемент не найден, возвращает -1, поэтому у вас есть шансы получить число от -1 до длины строки, тогдаMath.max
вы просто установите границы от 0 до длины, чтобы удалить шанс чтобы вернуть -1,0
совпадающего элемента в массиве, так и0
установить вMath.max()
; или в условном операторе OP. Посмотримvar value = Math.max( ["y"].indexOf("y"), 0 )
. Как определить, что0
возвращается?0
передается вMath.max()
вызов или0
отражает индекс"y"
внутри массива?Не совсем, просто используйте другую переменную.
Ваш пример обобщается примерно на это.
Вы тестируете вычисленное значение, а затем присваиваете это значение переменной, если она передает какой-то предикат. Способ избежать повторного вычисления вычисленного значения очевиден: использовать переменную для сохранения результата.
Я понимаю, что вы имеете в виду - похоже, должен быть какой-то способ сделать это, чтобы это выглядело немного чище. Но я думаю, что это лучший способ (идиоматически) сделать это. Если вы по какой-то причине часто повторяете этот шаблон в своем коде, вы можете написать небольшую вспомогательную функцию:
источник
РЕДАКТИРОВАТЬ: Вот оно, предложение об объединении значений Nullary теперь в JavaScript!
Использовать
||
const result = a ? a : 'fallback value';
эквивалентно
const result = a || 'fallback value';
Если приведение
a
кBoolean
возвратуfalse
,result
будет присвоено'fallback value'
, в противном случае значениеa
.Будьте в курсе края случае
a === 0
, когда отливают кfalse
иresult
будет (неправильно) принять'fallback value'
. Используйте подобные уловки на свой страх и риск.PS. В таких языках, как Swift, есть nil-coalescing operator (
??
), который служит аналогичной цели. Например, в Swift вы бы написали,result = a ?? "fallback value"
что довольно близко к JavaScriptconst result = a || 'fallback value';
источник
indexOf()
не может использоваться в этом шаблоне.||
работает в JavaScript? Если я вас правильно понимаю, то он работает иначе, чем многие другие основные языки (я думаю в первую очередь о C и его потомках [C ++, Java и т. Д.]). Даже если это действительно так||
работает в JavaScript, я бы посоветовал не использовать подобные уловки, требующие от сопровождающих особого знания языка. Хотя этот трюк и хорош, я считаю его плохой практикой.-1
. Опять же, я не могу говорить о JavaScript и его причудах, но, как правило-1
, это истинное значение, а не ложное, и поэтому ваш ответ не будет работать в случае вопроса и, конечно, не в общем случае, а будет работать только в конкретном ( но достаточно распространенный) подслучай.Используйте рефакторинг переменной extract :
Даже лучше с
const
вместоvar
. Вы также можете выполнить дополнительное извлечение:На практике используют более осмысленные имена , чем
index
,condition
иvalue
.источник
Вероятно, вы ищете оператора объединения. К счастью, мы можем использовать
Array
прототип для его создания:В дальнейшем это можно обобщить на ваш случай, добавив параметр к функции:
источник
for (let x in ['b','c']) console.log(x);
принты0
,1
,"coalesce"
.Лично я предпочитаю два варианта:
Чисто, если, как предложил @slebetman
Отдельная функция, которая заменяет недопустимое значение на значение по умолчанию, как в этом примере:
источник
Мне нравится ответ @leebetman. Комментарий под ним выражает озабоченность по поводу того, что переменная находится в «промежуточном состоянии». если это вас очень беспокоит, я предлагаю инкапсулировать его в функцию:
Тогда просто позвони
Вы могли бы выполнять более общие функции, если у вас есть их использование в других местах, но не переусердствуйте, если это очень специфический случай.
Но, честно говоря, я бы просто сделал это как @slebetman, если бы мне не нужно было повторно использовать из нескольких мест.
источник
Я вижу два способа взглянуть на ваш вопрос: вы либо хотите уменьшить длину строки, либо специально не хотите повторять переменную в троичном виде. Первый тривиальный (и многие другие пользователи публиковали примеры):
может быть (и должно быть, учитывая вызовы функций) сокращено следующим образом:
Если вы ищете более общее решение, которое предотвращает повторение переменной в тернарном виде, например:
где
foo
появляется только один раз. Отказ от решений вида:как технически правильно, но упущено из виду, значит, вам не повезло. Есть операторы, функции и методы, которые обладают кратким синтаксисом, который вы ищете, но такие конструкции по определению не являются тернарными операторами .
Примеры:
javascript, используя
||
для возврата RHS, когда LHSfalsey
:источник
Используйте вспомогательную функцию:
Теперь ваш код очень удобочитаем и не требует повторения.
Иерархия проблем кодирования:
Все ответы на странице пока кажутся правильными, но я думаю, что моя версия отличается высочайшей ясностью, что важнее краткости. Если вы не учитываете вспомогательную функцию - поскольку ее можно использовать повторно - она также является наиболее краткой. В чем-то похожем предложении использовать вспомогательную функцию, к сожалению, используется лямбда, которая, как мне кажется, просто скрывает то, что она делает. Для меня гораздо лучше более простая функция с одной целью, которая не принимает лямбда, а только значения.
PS Если вам нравится синтаксис ES6:
источник
translateValueIfEqual
было более наглядным, но я изменил его после того, как кто-то решил, что оно слишком длинное. Как иNz
функция в Access, если вы это знаете, вы это знаете, а если нет, то нет. В современных IDE вы можете просто нажать клавишу, чтобы перейти к определению. И запасным вариантом будет промежуточная переменная. Я не вижу здесь большого минуса.Думаю,
||
оператора можно настроить наindexOf
:Возвращаемое значение сдвигается вверх на 1, делая 0 из -1, что является ложным и поэтому заменяется вторым 1. Затем оно сдвигается назад.
Однако имейте в виду, что удобочитаемость лучше, чем исключение повторений.
источник
Это простое решение с побитовым НЕ и значением по умолчанию,
-1
которое позже обнуляется.Он работает в основном с двойным побитовым НЕ, которое возвращает исходное значение или значение по умолчанию, которое после применения побитового НЕ возвращает ноль.
Посмотрим на таблицу истины:
источник
Вы можете использовать переназначение:
&&
оператора для переназначения, потому что если первое условие ложно, второе выражение не будет оцениватьсяEx.
Показать фрагмент кода
источник
someArray.indexOf
выполняется только один разvalue
.-1
и0
; в противном случае этоmax()
был бы лучший вариантAgain, not seeking an answer to the exact question above
Учитывая пример кода на вопрос, не ясно , как это будет определено , что
3
является или не установлен на уровне индекса0
вsomeArray
.-1
возвращенный из.indexOf()
будет ценен в этом случае для исключения предполагаемого несоответствия, которое могло бы быть совпадением.Если
3
не входит в массив,-1
будет возвращено. Мы можем добавить1
к результату.indexOf()
для оценки какfalse
результат-1
, за которым следует||
OR
оператор и0
. Приvalue
ссылке вычтите,1
чтобы получить индекс элемента массива или-1
.Который ведет обратно просто используя
.indexOf()
и проверки-1
приif
условии. Или, определяя ,value
как ,undefined
чтобы избежать возможной путаницы в результате фактический оцениваемого состояния , относящегося к первоначальной ссылке.источник
Тернар похож на if-else, если вам не нужна часть else, почему бы вместо этого не использовать одно if ..
источник
В этом конкретном случае вы можете использовать короткое замыкание с помощью логического
||
оператора. Поскольку0
это считается ложным, вы можете добавить1
в свой индекс, таким образом, еслиindex+1
это так,0
вы получите правую часть логического - или в качестве своего результата, в противном случае вы получите свойindex+1
. Поскольку желаемый результат компенсируется1
, вы можете вычесть1
из него, чтобы получить свой индекс:источник