var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
有更好的写法吗?再次声明,我不是在寻求上面问题的确切答案,而是想要一个示例,说明何时可能会在三元运算符表达式中重复使用操作数...
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
有更好的写法吗?再次声明,我不是在寻求上面问题的确切答案,而是想要一个示例,说明何时可能会在三元运算符表达式中重复使用操作数...
就我个人而言,我认为最好的方法仍然是使用老式的if
语句:
var value = someArray.indexOf(3);
if (value === -1) {
value = 0;
}
value
技术上被改变了,而我尽量避免这种情况。 - Dave Cousineau代码应该易读,因此简洁并不意味着无论代价如何都应该变得过于简略 - 为了做到这一点,您应该转发到https://codegolf.stackexchange.com/ - 因此,我建议使用第二个本地变量命名为index
以最大化阅读理解能力(同时尽可能减少运行时间成本):
var index = someArray.indexOf( 3 );
var value = index == -1 ? 0 : index;
但如果你真的想要简化这个表达式,因为你对同事或项目合作者是一个残忍的虐待狂,那么你可以使用以下4种方法:
var
语句中使用临时变量你可以利用 var
语句定义(并赋值)第二个临时变量 index
的能力,用逗号分隔:
var index = someArray.indexOf(3), value = index !== -1 ? index: 0;
另一个选择是立即在定义后调用的匿名function
:
// 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
当您想在需要单个表达式的位置中包含多个表达式时,可以使用逗号运算符。
您可以使用它来引入副作用,在这种情况下通过重新分配给value
:
var value = ( value = someArray.indexOf(3), value !== -1 ? value : 0 );
这是因为var value
首先被解释执行(因为它是一条语句),然后是最左侧、最内层的value
赋值,再接着是逗号运算符的右操作数以及三元运算符——所有这些都是合法的 JavaScript 代码。
评论家@IllusiveBrian指出,如果将对value
的赋值用作括号化的子表达式,则无需使用逗号运算符(在前一个示例中):
var value = ( ( value = someArray.indexOf(3) ) !== -1 ? value : 0 );
注意,在逻辑表达式中使用否定词可能会让人们更难理解 - 因此以上所有示例都可以通过将 idx !== -1 ? x : y
更改为 idx == -1 ? y : x
或 idx < 0 ? y : x
来简化阅读。var value = ( ( value = someArray.indexOf(3) ) == -1 ? 0 : value );
var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
而不是使用逗号。 - IllusiveBrian_Self-executing anonymous function_
。由于只有一个参数,因此可以这样写:var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
。 - Alex Char关于数字
你可以使用 Math.max()
函数。
var value = Math.max( someArray.indexOf('y'), 0 );
如果结果大于等于0,则该函数将返回从0
到第一个大于0
的结果边界。如果indexOf
的结果为-1
,则它将返回0,因为0大于-1
。
对于布尔值和类布尔值
对于JS来说,我认为没有通用规则,特别是由于如何评估Falsy的值。
但如果有些东西能帮助你大部分时间,那就是或运算符(||
):
// 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
是一个假值。
3
或 "y"
不在 someArray
的索引 0
处? - guest271314Math.max
的例子中,indexOf
返回元素的索引,如果未找到元素,则返回-1,因此您有机会从-1到字符串长度获得数字,然后使用Math.max
将边界设置为0到长度以消除返回-1的可能性。 - Crisoforo Gaspar0
,也可以表示在OP中设置的Math.max()
中的0
;或者在条件运算符中。请考虑var value = Math.max( ["y"].indexOf("y"), 0 )
。如何确定返回哪个0
?是传递给Math.max()
调用的0
,还是反映数组中"y"
的索引的0
? - guest271314不用担心,只需使用另一个变量即可。
你的示例可以推广到类似以下的内容。
var x = predicate(f()) ? f() : default;
如果您正在测试一个计算出来的值,然后根据某些谓词为其赋值给一个变量,那么避免重新计算这个计算出来的值的方法是显而易见的:使用一个变量来存储结果。
var computed = f();
var x = predicate(computed) ? computed : default;
我了解你的意思 - 看起来应该有某种更简洁的方法来实现这个目标。但我认为这是最佳方式(习惯用语)来做到这一点。如果出于某种原因在代码中频繁重复这种模式,你可以编写一个小帮助函数:
var setif = (value, predicate, default) => predicate(value) ? value : default;
var x = setif(someArray.indexOf(3), x => x !== -1, 0)
使用||
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运算符(??
),其作用类似。例如,在Swift中,您可以编写result = a ?? "fallback value"
,这与JavaScript的const result = a || 'fallback value';
非常接近
indexOf()
无法在这种模式下使用。 - Barmar||
运算符的工作原理吗?如果我理解你的意思正确的话,那它与许多其他主要编程语言(主要是 C 及其派生语言 [C++, Java 等])的工作方式不同。即使这确实是 JavaScript 中 ||
的工作方式,我建议不要使用像这样的技巧,因为这需要维护人员了解关于该语言的特殊怪异之处。虽然这个技巧很酷,但我认为这是一种不良实践。 - Loduwijk使用提取变量重构:
var index = someArray.indexOf(3);
var value = index !== -1 ? index : 0
使用 const
而不是 var
更好。你也可以进行额外的提取:
const index = someArray.indexOf(3);
const condition = index !== -1;
const value = condition ? index : 0;
index
、condition
和value
更有意义的名称。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
原型来创建一个:
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
for (let x in ['b','c']) console.log(x);
输出 0
、1
、"coalesce"
。 - Charlie Harding我喜欢@slebetman的回答。下面的评论表达了对变量处于“中间状态”的担忧。如果这对你来说是一个大问题,那么我建议将其封装在一个函数中:
function get_value(arr) {
var value = arr.indexOf(3);
if (value === -1) {
value = 0;
}
return value;
}
var value = get_value( someArray );
如果在其他地方需要使用,您可以编写更通用的函数,但如果是非常特定的情况,请不要过度设计。
但说实话,除非需要从多个地方重复使用,否则我会像@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;
var value = foo || bar; // equivalent to !foo ? bar : foo
if
而不是if/else
。 - zer00ne3
不在数组someArray
的索引0
处? - guest271314Math.max(someArray.indexOf(3), 0)
呢? - 301_Moved_Permanently