Например, что-то вроде этого:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
Есть ли лучший способ, чтобы написать это? Опять же, я не ищу ответа на точный вопрос выше, просто пример, когда вы могли бы повторил операндов в тернарных выражений оператора...
Код должен быть читаемым, так сжатом, не значит быть немногословным любой ценой - для этого вы должны сделать репост к https://codegolf.stackexchange.com/ - так что вместо этого я бы рекомендовал использовать второй локальную переменную с именем index
, чтобы увеличить значение постижимости (при минимальном времени выполнения, стоимости тоже, замечу):
var index = someArray.indexOf( 3 );
var value = index == -1 ? 0 : index;
Но если вы действительно хотите, чтобы сократить это выражение, потому что вы'снова жестокий садист для своих коллег или сотрудников проекта, то вот 4 подходов, которые можно использовать:
ВАР
заявлениеВы можете использовать ВАР
заявление'с умение определять (и назначить) индекс второй временной переменной, когда через запятую:
var index = someArray.indexOf(3), value = index !== -1 ? index: 0;
Другим вариантом является самостоятельное выполнение анонимной функции:
// Traditional syntax:
var value = function( x ) { return x !== -1 ? x : 0 }( someArray.indexOf(3) );
// ES6 syntax:
var value = ( x => x !== -1 ? x : 0 )( someArray.indexOf(3) );
Тут еще и пресловутый "и оператор на" запятая; что JavaScript поддерживает, который также присутствует в C и C++.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
вы можете использовать оператор запятая, когда вы хотите включить несколько выражений в месте, которое требует более одного выражения.
Вы можете использовать его, чтобы представить побочных эффектов, в данном случае переподчиненных "значение":
var value = ( value = someArray.indexOf(3), value !== -1 ? value : 0 );
Это работает, потому что ВАР значением
интерпретируется во-первых (как это'заявление), а потом самый левый, внутренний-самое "значение" задание, а затем правую руку оператор запятая, а затем тернарного оператора - все права на JavaScript.
Комментатор @IllusiveBrian указал, что использование запятой-оператор (в предыдущем примере) не требуется, если задание "значение" используется как часть выражения в скобках:
var value = ( ( value = someArray.indexOf(3) ) !== -1 ? value : 0 );
Обратите внимание, что использование негативов в логических выражениях могут быть тяжелее для человека, чтобы следовать - так что все вышеперечисленные примеры могут быть упрощены для чтения, изменив в IDx !== -1 ? Х : Y
для в IDx == -1 ? г : х
:
var value = ( ( value = someArray.indexOf(3) ) == -1 ? 0 : value );
Числа
Вы можете использовать математику.функция Макс ()`.
var value = Math.max( someArray.indexOf('y'), 0 );
Он будет держать границы результата от 0
до первого результата больше 0
, если это'ы в случае. И если результат от помощи indexOf
это -1
он будет возвращать 0, как больше чем -1
.
Для логических и булевых значений y
Для JS нет общего правила, насколько мне известно, специально, так как ложь значения вычисляются.
Но если что-то может помочь вам большую часть времени оператор OR (||
):
// Instead of
var variable = this_one === true ? this_one : or_this_one;
// you can use
var variable = this_one || or_this_one;
Вы должны быть очень осторожны с этим, потому что в вашем первом примере помощи indexOf
может возвращать 0
и если оценивать 0 || -1
Она вернется -1
, потому что 0
- это ложь значение.
Не совсем, просто использовать другую переменную.
Ваш пример обобщается на что-то вроде этого.
var x = predicate(f()) ? f() : default;
Вы'повторного тестирования вычисленное значение, затем присвоить это значение переменной, если оно проходит несколько сказуемого. Кстати, чтобы избежать повторного вычисления вычисленного значения очевидна: используется переменная для хранения результата.
var computed = f();
var x = predicate(computed) ? computed : default;
Я понимаю, что вы имеете в виду - кажется, что там должен быть какой-то способ сделать это, что выглядит немного чище. Но я думаю, что's самый лучший способ (идиоматически) для этого. Если вы были повторять этот рисунок много в коде по какой-то причине, вы могли бы написать небольшую вспомогательную функцию:
var setif = (value, predicate, default) => predicate(value) ? value : default;
var x = setif(someArray.indexOf(3), x => x !== -1, 0)
Используйте ||
результат от const = а ? ответ : 'запасное значение';
эквивалентно
результат от const = а || 'резервное значение';
Если отливки A
до логического
возвращает значение false
, результат
будет присвоено 'резервное значение', в противном случае значение
а`.
Быть в курсе крайний случай а === 0
, которое бросает на false
и результат
будет (неправильно) принять 'резервное значение'
. Используйте это на свой страх и риск.
ПС. Такие языки, как у Свифта есть шь-коалесцирующий оператор (??
), который служит подобной цели. Например, в Swift вы хотели написать результат = а ?? на "запасной вариант значения"
в котором находится довольно близко к JavaScript'результат S как const = а || 'резервное значение';
Используйте экстракт переменной рефакторинг:
var index = someArray.indexOf(3);
var value = index !== -1 ? index : 0
Это даже лучше с константный
вместо ВАР
. Вы также можете сделать дополнительную добычу:
const index = someArray.indexOf(3);
const condition = index !== -1;
const value = condition ? index : 0;
На практике, использовать более осмысленные имена, чем "индекс", "условие" и "значение".
const threesIndex = someArray.indexOf(3);
const threeFound = threesIndex !== -1;
const threesIndexOrZero = threeFound ? threesIndex : 0;
Лично я предпочитаю два варианта:
Чисто если, как @slebetman предложил
Отдельную функцию, которая заменяет недопустимое значение по умолчанию, как в этом примере:
в
function maskNegative(v, def) {
return v >= 0 ? v : def;
}
Array.prototype.indexOfOrDefault = function(v, def) {
return maskNegative(this.indexOf(v), def);
}
var someArray = [1, 2];
console.log(someArray.indexOfOrDefault(2, 0)); // index is 1
console.log(someArray.indexOfOrDefault(3, 0)); // default 0 returned
console.log(someArray.indexOfOrDefault(3, 123)); // default 123 returned
в
Вы'повторно, вероятно, ищете коалесцирующий оператора. К счастью, мы можем использовать массив
прототипом для создания одного:
Array.prototype.coalesce = function() {
for (var i = 0; i < this.length; i++) {
if (this[i] != false && this[i] != null) return this[i];
}
}
[null, false, 0, 5, 'test'].coalesce(); // returns 5
Это может быть обобщен в вашем случае, путем добавления параметра функции:
Array.prototype.coalesce = function(valid) {
if (typeof valid !== 'function') {
valid = function(a) {
return a != false && a != null;
}
}
for (var i = 0; i < this.length; i++) {
if (valid(this[i])) return this[i];
}
}
[null, false, 0, 5, 'test'].coalesce(); // still returns 5
[null, false, 0, 5, 'test'].coalesce(function(a){return a !== -1}); // returns null
[null, false, 0, 5, 'test'].coalesce(function(a){return a != null}); //returns false
Мне нравится @slebetman'ы ответ. Комментарий под ним выражают беспокойство по поводу переменной в собой "промежуточное состояние на". если это является большой проблемой для вас, то я предлагаю инкапсулировать его в функцию:
function get_value(arr) {
var value = arr.indexOf(3);
if (value === -1) {
value = 0;
}
return value;
}
Тогда просто позвоните
var value = get_value( someArray );
Вы могли бы сделать более универсальные функции, если у вас есть использование для них в других местах, но Дон'т-инженера, если он's очень конкретном случае.
Но если честно, я бы просто сделать как @slebetman, если мне нужно, чтобы повторно использовать из нескольких мест.
Существует два способа я могу видеть, глядя на ваш вопрос: вы либо хотите уменьшить длину линии, или вы конкретно хотите, чтобы избежать повторения переменных в тройных. Первый-тривиальный (и многие другие пользователи выложили примеры):
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0;
может быть (и должно быть, учитывая вызовы функций) сокращено следующим образом:
var value = someArray.indexOf(3);
value = value !== -1 ? value : 0;
Если вы ищете более общие решения, что предотвращает повторения переменных в тройных, вот так:
var value = conditionalTest(foo) ? foo : bar;
где с Foo
появляется только один раз. Отбросив решений формы:
var cad = foo;
var value = conditionalTest(foo) ? cad : bar;
как технически правильно, но упускаешь главное, то вам не повезло. Есть операторы, функции и методы, которые имеет лаконичный синтаксис, который вы ищете, но такие конструкции по определению, разве'т ternary operators.
Примеры:
в JavaScript, используя||
, чтобы вернуться РГО при ЛХС falsey
:
var value = foo || bar; // equivalent to !foo ? bar : foo
Использовать вспомогательную функцию:
function translateValue(value, match, translated) {
return value === match ? translated : value;
}
Теперь ваш код очень читабельный, и там's нет повторения.
var value = translateValue(someArray.indexOf(3), -1, 0);
Иерархия касается кодирования:
Все ответы на этой странице указаны правильно, но я думаю, что моя версия имеет высокую четкость, что является более важным, чем лаконичность. Если вы Don'т рассчитывать вспомогательную функцию—как она может быть использована—это самый лаконичный, а также. Несколько аналогичное предложение использовать вспомогательную функцию, к сожалению, использует лямбда-выражения, что для меня, просто скрывает, что это'ы делаешь. Проще работать с одной целью, что не'т принять лямда, просто значения, мне гораздо лучше.
P. S. Если вам нравится на ES6 синтаксис:
const translateValue = (value, match, translated) => value === match ? translated : value;
let value = translateValue(someArray.indexOf(3), -1, 0); // or const
Я думаю, что оператор ||
могут быть адаптированы к помощи indexOf
:
var value = ((someArray.indexOf(3) + 1) || 1) - 1;
Возвращаемое значение сдвигается вверх на 1, что делает 0 из -1, который является falsey и поэтому заменяется второй 1. Затем он сдвигается назад.
Однако, пожалуйста, имейте в виду, что удобочитаемость выше, чтобы избежать повторения.
Это простое решение с побитового NOT и значение по умолчанию -1
, что приводит впоследствии к нулю.
index = ~(~array.indexOf(3) || -1);
Он работает в основном с двойным побитового не, которое возвращает исходное значение или значение по умолчанию, которое после нанесения побитовый оператор not возвращает ноль.
Позвольте'ы посмотрите на таблицу правду:
метод indexOf ~метод indexOf значение логическое значение по умолчанию результат комментарий
-1 0 falsy -1 -1 0 take default value
0 -1 truthy -1 0
1 -2 truthy -2 1
2 -3 truthy -3 2
Можно использовать повторно задание:
Экс.
var value = someArray.indexOf(3);
value == -1 && (value=0);
в
var someArray = [4,3,2,1];
var value = someArray.indexOf(1);
value == -1 && (value=0);
console.log('Found:',value);
var value = someArray.indexOf(5);
value == -1 && (value=0);
console.log('Not Found:',value);
в
В данном конкретном случае, вы могли бы использовать замыкания с оператором логического||
. Как 0
является ложь, вы можете +1
к индексу, таким образом, если индекс+1и
0, то вы'll получают право стороны возвратить в качестве результата, в противном случае, вы'll получить свой индекс+1
. Вы можете затем -1
от этого результата, чтобы получить свой индекс:
в
const someArray = [1, 2, 3, 4];
const v = ((someArray.indexOf(3)+1) || 1)-1;
console.log(v);
в
Приведенный пример кода в вопрос не ясно, как будет определяться, что 3
или не установлен в индекс 0
на someArray
. -1
вернулся из .метод indexOf()
будет ценным в этом случае, для того, чтобы исключить предполагаемой нематчевые, которые могут быть матч.
Если 3
не входит в массив, -1
будет возвращен. Мы можем добавить 1
в результате .метод indexOf ()
, чтобы оценить как false
в результате -1
, где следует | |
илиоператора
0. Когда "значение" ссылается, вычесть
1, чтобы получить индекс элемента массива или
-1`.
Что приводит к простое использование .метод indexOf()
и -1
В если
условие. Или, определять значение
, как не определено
, чтобы избежать возможной путаницы, как фактический результат оценивали условие, касающееся оригинальной ссылкой.
в
var someArray = [1,2,3];
var value = someArray.indexOf(3) + 1 || 1;
console.log(value -= 1);
var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || 1;
// how do we know that `4` is not at index `0`?
console.log(value -= 1);
var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || void 0;
// we know for certain that `4` is not found in `someArray`
console.log(value, value = value || 0);
в