为什么应该使用 Array.some 而不是“for”循环或 forEach?
在本文中,我们将了解为什么应该使用Array.some而不是Array.forEach(或)for 循环。
客观的
在给定的数组中,查找学生是否有任何一门科目不及格。学生的及格标准是所有科目至少获得 40 分。
const marks = [
{ name: "English", mark: 80 },
{ name: "Maths", mark: 100 },
{ name: "Science", mark: 38 },
{ name: "Social", mark: 89 }
];
传统方法
解决方案 1:使用 Array.forEach
let isFailed = false;
marks.forEach((subject) => {
console.log("checking subject => " + subject.name);
if (subject.mark < 40) {
// failed
isFailed = true;
}
});
console.log("Is student failed => " + isFailed);
输出:
checking subject => English
checking subject => Maths
checking subject => Science
checking subject => Social
Is student failed => true
该学生不及格,因为他没有达到科学科目的及格标准。
但是,如果你看一下输出结果,就会发现没有必要检查社会科目,因为他科学科目不及格,而科学科目又排在社会科目之前。所以,为了避免进一步检查,我们可以更新现有代码,如下所示:
let isFailed = false;
marks.forEach((subject) => {
// added this condition to prevent further checking
if (!isFailed) {
console.log("checking subject => " + subject.name);
if (subject.mark < 40) {
// failed
isFailed = true;
}
}
});
console.log("Is student failed => " + isFailed);
输出:
checking subject => English
checking subject => Maths
checking subject => Science
Is student failed => true
看起来我们已经解决了问题,但事实并非如此。即使我们将逻辑封装在if
代码块中,迭代仍然会发生。尝试添加else代码块来检查一下。
想象一下,如果数组中有 1000 个元素,并且失败条件位于第 10 个位置,那么剩下的990 次迭代仍然会运行,这是不必要的。这既耗时又耗计算。🤯
所以,这是解决这个问题的错误方法。❌
让我们继续讨论第二种传统方法。
解决方案 2:使用 for() 循环
let isFailed = false;
for (i = 0; i <= marks.length; i++) {
const subject = marks[i];
console.log("checking subject => " + subject.name);
if (subject.mark < 40) {
// failed
isFailed = true;
// prevents further execution
break;
}
}
console.log("Is student failed => " + isFailed);
这个解决方案比之前的方法更好。原因是,当满足失败条件时,进一步的迭代会通过break
关键字停止。
break 语句用于跳出循环
这种方法的问题在于,它不是解决这个问题的正确方法。就像我们使用for循环和Array.forEach来迭代数组一样,Array 中有一个内置的方法来解决这个问题。
所以,这也不是一个正确的解决方案。❌
让我们在下一节中拭目以待!
正确的方法
解决这个问题的正确方法是使用Array.prototype.some()
。
来自MDN,
some() 方法测试数组中是否至少有一个元素通过了所提供函数实现的测试。如果在数组中找到一个元素,且所提供函数的测试结果为 true,则返回 true;否则返回 false。该方法不会修改数组。
这就是我们想要的。如果至少一个元素满足条件,则返回true ,否则返回false。
以下是我们问题的解决方案,
const isFailed = marks.some((subject) => subject.mark < 40);
console.log("Is student failed => " + isFailed); // true
一切按预期进行。解决方案就一行。🤯
但是,我们如何知道,一旦条件满足,进一步的执行是否会停止?
让我们通过更新代码来检查一下。
const isFailed = marks.some((subject) => {
console.log("checking subject => " + subject.name);
return subject.mark < 40;
});
console.log("Is student failed => " + isFailed);
输出:
checking subject => English
checking subject => Maths
checking subject => Science
Is student failed => true
代码按预期工作。
所以,这是解决我们问题的正确解决方案。✅
现在,该代码比其他方法更具可读性、更简单、更高效。
我希望您喜欢这篇文章或发现它对您有帮助。
你可以在Twitter和Github上联系我🙂