如果我有一份需要满足这些要求的国际单项体育联合会声明:
1
| if(cave > 0 && training > 0 && mobility > 0 && sleep > 0) |
有没有办法说所有的都大于零?只是为了更有效的干代码?
类似:
1
| if(cave, training, mobility, sleep > 0) |
- 如果这些值只能为0或正(从不为负,或从不非常大),则有一个很好的答案。
- @我也想到了!
- if (cave && training && mobility && sleep)有什么问题?
- @如果值永远不能为负,Alex就会工作。
- 是的,消极的事情是个问题!虽然谢谢
- 如果有更多的变量参与进来呢…
- @亚历克斯,如果其中一个值是0,另一个值是4,它将通过你的测试(并且不通过OP的要求)。
- @Jamesdonnelly真:P
- 原始陈述有什么问题?1。这很简单。2。简洁明了。三。很清楚。4。它做的正是你想要它做的。本页上没有其他建议可以满足所有这些要求。
- 这个线程充满了设计过度和可爱的代码示例。你的if语句没有错。如果您有四个以上的条件,我建议您使用中间标志(valid_location && valid_status)。
- 我不认为在一次if语句中多次使用&& > 0会违反dry。如果您必须在多个地方使用相同的条件集,那么将它放在函数中或该"类"的原型中。聪明只会让别人调试时更烦人。
- 最明显的解决办法是:if(cave > 0 && training > 0 && mobility > 0 && sleep > 0)。如果它使代码更容易阅读,那么应该将条件拉入单独的函数中。
- 无论出于什么原因,这类问题都会给程序员带来最坏的答案。就好像我们被迫找到不寻常和聪明的答案。您的工作是编写易于理解的代码。一个衬板不会给你更多的点数(至少在stackoverflow之外)。
- @Isanae,这就是问题所在,在我的实际代码中,我还有另外8个这样的代码,它覆盖了两行,我只是简化了一点,让它在堆栈中保持更简单。但当我有12个条件,他们都需要超过0,我希望有一个更微妙的方法!
- @奥利克林,那么你可能问错了问题。通过发布代码检查中涉及的所有代码或者在堆栈溢出的另一个问题中,您可能会得到更好的服务。如果我们有完整的图片,你会得到更好的答案。
- @Ollieklein,如果你有12个条件,每个条件都需要计算(而不仅仅是在一些数据库中查找),你真的需要考虑你的整体逻辑!您可能需要将其更改为早期回报,即cave = ... calculcation ...; if (cave <= 0) return; training = ... calculation ...; if (training <= 0) return;。计算12个条件,并在一次失败时终止,是浪费了大量的计算…
使用math.min可以得到最小值,然后只需要对下限进行一次检查。
1 2 3
| if(Math.min(cave, training, mobility, sleep) > 0) {
//do something
} |
- 这是我看到的简单而好的答案…:)
- 这是聪明,简洁,而且仍然清晰。
- 非常干净,容易理解。
- 这就是为什么简单、聪明、简洁和干净的代码不一定是好代码的原因。代码是关于意图的。如果遇到这种情况,我将不得不花时间去弄清楚1)这段代码在做什么,2)为什么要这样写。最后,我会生气的,我会恢复你的更改,我会确保你在下一年得到强制性的代码审查。
- @Rilezg我们每天都用简单的条件解析if语句。这几乎不费吹灰之力。这不是成语。它必须被分析、理解和学习。为了什么?
- @不过,如果是这样的话,0值应该是一个常量/变量,这样您就可以在一个位置更改它,而且很清楚该值的含义。
- 我看你的回答没有错。真的很聪明。不可读?有点,但与使用bitwise XOR的相比,这是一片天堂
- 我会非常明确地评论这一点——任何不明显的行为都应该(以及许多明显的行为)。
- @伊斯梅尔的比较应该是与原始代码,而不是最坏的修改建议。
- @Kylestrand哼?什么!?
- @ismael原始代码可读性很强。当原答案优于两个答案时,为什么要将此建议答案与其他建议答案进行比较?
- @Kylestrand怎么样更好?
- @IsmaelMiguel这个建议涉及使用数学库进行简单的逻辑检查。这不太清楚,而且不太可能是值得改进的性能(如果它确实提高了运行时效率的话)。另请参见Isanae的评论。
- @Kylestrand:再看看我为什么称赞这段代码的原因吧?
- @Ismael你最初的评论提到了"位或"。这就是我批评的其他低级建议的比较。
- @Kylestrand引述:"另见Isanae的评论"
- 让我们在聊天中继续讨论。
- +一个聪明的答案!所有认为这不可读的人:预先添加一条评论!这又甜又快又简单,干得好
可以将数组与.every一起使用。这不太干,但更详细:
1 2 3 4 5 6
| var isGreaterThanZero = function(val) {
return val > 0;
};
if([cave, training, mobility, sleep].every(isGreaterThanZero)) {
// Do Something
} |
我喜欢这样做的原因是,通过使用数组,很明显您在为每个变量重复逻辑。以一种明显的方式命名回调有助于未来的读者准确理解这种检查将实现什么。最后,这不仅为数字提供了范围,还为将来任何类型的检查提供了范围——任何复杂性都隐藏在if语句本身之外。
- 你也可以使用some。
- if语句中的所有数组必须是同一类型,对吗?String或Integer等。
- 这对使用
- @Alex Polyfill在链接页上。.@Altay Mazlum编号。这里没有类型检查。如果需要,可以添加到helper函数中。
- 这还有一个额外的好处,即允许使用一个更有意义的名称,如statPositive。它甚至可以通过将val > 0函数包装在另一个接受列表的函数中进行轻微修改:if(allStatsPositive([cave, training, .... ]))将非常清楚。
正如一些人所说,在if语句中使用多个简单条件没有任何错误,但是我会考虑将格式改为:
1 2 3 4
| if ( cave > 0
&& training > 0
&& mobility > 0
&& sleep > 0 ) |
或者,我将从使用这些变量作为整数改为bool变量,即isCave、hasTraining或类似变量,然后将适当的bool设置为更接近代码定义不同属性的位置(编辑:如果为false,可能会提前返回,以防止进一步的不必要的计算)。这将在下一个代码块中将if语句简化为后者,此外,它还显示了一个变量,如果条件变得稍微复杂,或者您希望简化if语句的读取:
1 2 3 4 5 6 7 8
| var isCave = cave > 0; # What does cave > 0 mean?
var hasTraining = training > 0;
var isMobile = mobility > 0;
var isNotSleeping = sleep > 0; # What does sleep > 0 indicate? Unclear
if (isCave && hasTraining && isMobile && isNotSleeping ) {
// Do your thing
} |
换句话说,if语句中的多个条件不是您最大的代码味道,我将把重点转移到为您的变量提供更好的名称,清楚地指示值的含义。这将提高对代码的阅读和理解,这比一些奇怪的语法更能避免多个if条件。
在if语句中使用多个简单条件没有任何错误。但是,如果它不能放在一行中(大约80个字符),您就有一些解决方案。
最终,您不会检查四个变量是否大于零。您正在检查一组条件。这些条件(当前)由有符号整数表示的事实不仅不相关,而且是应该隐藏在函数中的实现细节。
使用中间标志:
10
使用函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function can_do_this()
{
// split conditions into logical groups
// checking location, because you need training if you're
// in a cave
if (cave <= 0 || training <= 0)
return false;
// checking status, because you have to be mobile and
// sleepy
if (mobility <= 0 || sleep <= 0)
return false;
return true;
}
if (can_do_this())
// ... |
针对需要检查的个别条件使用函数:
1 2 3 4 5 6 7 8 9 10 11 12
| function valid_location()
{
return (cave > 0 && training > 0);
}
function valid_status()
{
return (mobility > 0 && sleep > 0);
}
if (valid_location() && valid_status())
// ... |
- 请做一个简单的var valid_status = (mobility > 0 && sleep > 0);。
- @我实际上写了一些东西,我删掉了。我想人们会理解布尔表达式可以被使用,除非它太难阅读或者有太多的条件。经验丰富的程序员会知道这一点,我不希望新手认为把所有这些都塞进一行是件好事。所以不,我可能不会改变它。
- 你说的"把所有的东西都塞进一行"是什么意思?无论表达式是在赋值条件中还是在if条件中,都不重要,它仍然是"一行"。使用if/else设置布尔变量只是一个不好的实践,特别是对于初学者来说。
- @Bergi这个问题是关于有很多标志要测试。我不喜欢在作业的右边有很多东西。我更喜欢把它写在if的声明中。我担心,通过使用表达式初始化标志,我会含蓄地说右侧的复杂表达式是好的。
- 我不是说你应该用一个复杂的表达。我只是说,当将它们拆分(这是解决问题的正确方法)时,就像您在第一个代码片段中所做的那样,您不应该将这些部分放入有条件地初始化helper标志的if语句中—您应该直接分配helper标志。
- @我理解您希望我直接初始化标志,而不是有条件地分配它们。我是说我同意var valid_status = (mobility > 0);,但我会用if来表达更复杂的表达。
- @伊莎娜,新手程序员需要学会将布尔表达式看作是另一种类型的表达式,与对数字或字符串的操作没有什么不同。如果他们能避免的话,他们还需要学会不要隐藏诸如变量重新分配之类的副作用。在项目1中,可以通过初始化布尔表达式中的变量来解决这些问题,然后再也不更新它们。
- @总的来说,我同意你的建议,即应该重新构造像OP这样的代码,以明确其意图。
正如其他人所建议的,您可以使用。如果您不介意使用ES6或Polyfills:
1 2 3 4
| var hasAllStats = [cave, training, mobility, sleep]
.every(function(stat) { return stat > 0; });
if (hasAllStats) { } |
或者,您可以使用.some来获取反转(还需要es6或polyfill):
1 2 3 4
| var isMissingStats = [cave, training, mobility, sleep]
.some(function(stat) { return stat <= 0; });
if (!isMissingStats) { } |
如果不想使用ES6,可以使用Reduce:
1 2 3 4 5 6
| var hasAllStats = [cave, training, mobility, sleep]
.reduce(function(hasAllStats, stat) {
return hasAllStats && stat > 0;
}, true);
if (hasAllStats) { } |
- 这将丢失0到1之间的数字。
- 这更符合给定的规则:.reduce(function(memo, stat) { return memo && stat > 0; }, true)。
- @打得很好。
听起来像是"验证器"函数的工作,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12
| function areAllGreaterThanZero(){
//TODO: check inputs
var result = true;
[].splice.apply(arguments).forEach(function(x){
result = result && (x > 0);
});
return result;
}
if(areAllGreaterThanZero(cave, training, mobility, sleep)) {
// ...
} |
假设32位整数。
1
| if ((cave | training | mobility | sleep) > 0) |
如果上述任何一个数字为负数,或的结果将为负数,并且不满足要求。
编辑:任何一个参数为0时都不起作用。这是可行的,但它不会像其他方式那样高效、易读。
1
| if (((cave | training | mobility | sleep) > 0) && (cave*training*mobility*sleep != 0)) |
另一个更好的方法
1
| if (!((cave | training | mobility | sleep) < 0)) |
- 你是对的,这是正确的方法,应该标记为正确答案。
- 请注意,这不适用于任何其他不属于0的情况,尽管如此,聪明的工作
- 如果cave等于0,其余变量为正,则OR语句的结果为正。但这不是所需的结果;它返回操作代码的相反结果。
- 先为人编写代码,然后为机器编写代码。我保证我可以在我们的代码库中看到if(cave > 0 && training > 0 && mobility > 0 && sleep > 0),但是任何像if ((cave | training | mobility | sleep) > 0)这样聪明的东西都会让我恼火,因为我不知道它是否真的符合你的意图。如果我说不出你的意思,我能搞清楚它是干什么的没关系。省去解决问题的聪明,而不是创造问题。
- 当然,在这里的第二个答案中,您只需要将它们相乘并检查它是否大于0?第一次检查是多余的吗?
- @备注:如果它们都是负的,那么乘以它们将得到一个非零和正的答案。
- 这并不能保证对非整数有效。0.2|0.5|0.6|0.9为零。
- 注意,JS中的位运算符假定为32位整数,因此大于32位的负数将被截断为低32位。因此,数字的符号现在取决于最高有效位是0还是1。例如,-2340293804 | 5返回一个正数,因为当截断为32位整数时-2340293804 msb为0。
- @我知道它只适用于32位int。
- @我已经修好了
- @我不是在说可读性。原来的方法if(cave > 0 && training > 0 && mobility > 0 && sleep > 0)显然是最容易阅读的方法,比这个问题的答案容易得多。如果手术要求另一种方法,我会回答另一种可能(有时更有效)的方法。他没有说它一定比他的版本更容易阅读,只是更容易打字和干燥。对于dry,您必须使用一个函数,它表示无论如何都有意义。可能需要函数中的一些注释
- 嘿,怎么了?
- @ L?紫外线?nhph&250;c我之前的评论是对操作人员(以及考虑不可读解决方案的任何其他人)的警告。这是一个警告,首先不要请求这样的代码。你的答案是所要求的类型,这是一个很好的解决方案的例子,不幸的是错过了边缘案例并使读者困惑,所以我在这里提出了关注。对不起,我没有说清楚我在跟谁说话。
用木屑过滤:
1 2 3 4
| var data = [cave, training, mobility, sleep];
var result = _.filter(data, function (datum) { return datum > 0; }).length === data.length;
console.log(result); |
它迭代数组元素并返回由满足给定要求的元素组成的新数组,这些元素是> 0—如果结果数组的大小与给定的不同,则表示其中一个或多个元素不是> 0。
我专门写它是为了检查每个数组值(即使没有必要,因为第一个> 0可以给出相同的结果),而不是像您所说的那样,在第一个正数处停止检查所有数组值。
PS您可以反转它来检查<= 0和.length === 0是否安装得更快。
为什么要寻找解决方案?
Your question looks like best and simple answer, i recommend it. We have multiple solutions for this. Below one is that.
.every()的jsbin
通过使用每种功能来实现。
1 2 3 4 5 6 7
| var flag = [cave, training, mobility, sleep].every(function(val) {
return val > 0;
});
if(flag) {
alert('All the elements are greater than Zero');
} |
- 在if语句中添加此项的外观
- 如果任何(不是全部)值都大于零,则返回true。
- 如果你选择ES5,你需要的是.every(),而不是.some()(如rgraham的最上面的答案所述)
- @亚历克斯把它放在功能里