具有嵌套 forEach 和 for 循环的函数不会返回 false
Posted
技术标签:
【中文标题】具有嵌套 forEach 和 for 循环的函数不会返回 false【英文标题】:Function with nested forEach and for loop won't return false 【发布时间】:2020-07-16 22:30:49 【问题描述】:我正在做一个algorithm challenge 来练习 JS。我有一个通过循环运行的程序,当满足条件时,函数应该返回 false。但是,当条件满足时,返回不起作用,函数总是以返回 true 结束。
const isDiagonalLeftWristband = (band) =>
band.forEach((row, y) =>
row.forEach((item, x) =>
for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++)
if (band[y][x] !== band[y+i][x+i])
console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
return false;
)
)
return true;
const band3 = [
["A", "B", "C"],
["C", "Z", "B"],
["B", "C", "A"],
["A", "B", "C"]
];
console.log(isDiagonalLeftWristband(band3))
输出:
false //from console log
false //from console log
true //from function return statement
任何帮助将不胜感激!
【问题讨论】:
【参考方案1】:return false
只会退出 (item, x) =>
匿名函数,而不是像您期望的那样退出 isDiagonalLeftWristband()
。在两个forEach
被执行后,isDiagonalLeftWristband()
将始终以return true
结束。您可以使用循环来避免这个问题。
const isDiagonalLeftWristband = (band) =>
for (let [y, row] of band.entries())
for (let [x, item] of row.entries())
for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++)
if (band[y][x] !== band[y+i][x+i])
console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
return false;
return true;
const band3 = [
["A", "B", "C"],
["C", "Z", "B"],
["B", "C", "A"],
["A", "B", "C"]
];
console.log(isDiagonalLeftWristband(band3))
forEach
并非旨在提前终止。它总是会遍历所有元素。 (它的名字:))。来自 MDN 文档:
没有其他方法可以停止或中断 forEach() 循环 抛出异常。如果你需要这样的行为,forEach() 方法 是错误的工具。
可以通过以下方式提前终止:
A simple for loop A for...of / for...in loops Array.prototype.every() Array.prototype.some() Array.prototype.find() Array.prototype.findIndex()
数组方法:every()、some()、find() 和 findIndex() 测试数组 带有返回真值的谓词的元素以确定是否 需要进一步迭代。
您可以改为使用建议的函数之一,该函数旨在使用谓词测试数组的元素。 every()
测试数组的所有元素是否都通过了一些测试;这至少在语义上是您所需要的。
const isDiagonalLeftWristband = (band) =>
return band.every((row, y) =>
return row.every((item, x) =>
for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++)
if (band[y][x] !== band[y+i][x+i])
return false;
return true;
);
);
const band3 = [
["A", "B", "C"],
["C", "B", "B"],
["B", "C", "A"],
["A", "B", "C"]
];
console.log(isDiagonalLeftWristband(band3))
【讨论】:
这已经解决了我的问题,但是为了学习,有没有办法让函数与forEach一起工作? Naoufal 的答案是一个可能的解决方案,但就像他指出的那样,他的解决方案在找到第一个错误后不会退出。 @NicholasNewman 我已经编辑了我的答案来回答你的问题。简而言之,没有明智的方法可以提前终止 forEach。【参考方案2】:return false;
语句只将值返回给它所属的函数,即
(item, x) =>
for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++)
if (band[y][x] !== band[y+i][x+i])
console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
return false;
您的代码必须以一种可以将 false 返回给主函数的方式工作,您可以使用这种方法:
const isDiagonalLeftWristband = (band) =>
let returnValue = true;
band.forEach((row, y) =>
row.forEach((item, x) =>
for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++)
if (band[y][x] !== band[y+i][x+i])
console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
returnValue = false;
// return false;
)
)
return returnValue;
domondo 建议的更好,因为一旦找到第一个 false
,该函数就存在
【讨论】:
以上是关于具有嵌套 forEach 和 for 循环的函数不会返回 false的主要内容,如果未能解决你的问题,请参考以下文章
在 VBA 中是不是有循环类型、函数或方法来清理 HTML 文件中节点的嵌套 For Each 循环?
使用具有多个参数和索引的lapply / sapply减少函数内的嵌套循环
如何在 Nightwatch 测试的自定义命令中添加嵌套函数 javascript - forEach - 循环遍历元素