如何在TypeScript中打破ForEach循环

94

我有以下代码,但在特定条件下无法跳出循环。

function isVoteTally(): boolean {
  let count = false;
  this.tab.committee.ratings.forEach((element) => {
    const _fo = this.isEmptyOrNull(element.ratings.finalOutcome.finaloutlook);
    const _foreign = this.isEmptyOrNull(element.ratings.finalOutcome.foreign);
    const _local = this.isEmptyOrNull(element.ratings.finalOutcome.local);
    const _tally =
      element.ratings.finalOutcome.voteTally.maj +
      element.ratings.finalOutcome.voteTally.dis;

    if (_fo == false && _foreign == false && _local == false) {
      if (_tally > 0) {
        return (count = false); // ⭐
      }
    } else {
      if (_tally < 0) {
        return (count = false); // ⭐
      }
    }
  });
  return count;
}

在星标区域,我想破译代码并返回布尔值,但我无法做到。应该如何实现?


4
MDN是JavaScript和可用类型/方法的重要资源。这里是Array.ForEach页面链接。它还有一个专门介绍在需要中断时可以使用的替代方法的部分,可用于"提前终止"。 - user310988
请将最佳答案更新为@Roberc提供的答案。 - Kunal
这个回答解决了你的问题吗?像调用break一样短路Array.forEach - Liam
问题也应该重命名为:如何在TypeScript中通过返回值打破ForEach循环。目前标题有点误导,因为您可以通过返回空来打破forEach循环。 - C0mpl3x
来自@user310988的评论是我在搜索了数十分钟后看到的最佳答案。Roberc的回答只解决了一种情况,因此不应该被接受为答案。在海量的错误/不完整的答案中,我终于找到了正确的答案。 - Wolf
这需要一个[mre]。我不会编辑它变成一个,因为我不确定这是否是我的职责。 - starball
7个回答

153

this.tab.committee.ratings.forEach 不是一个运算符。

Typescript 允许更易读的代码。

使用以下样式的 for 循环:

for (let a of this.tab.committee.ratings) {
   if (something_wrong) break;
}

p.s. 在 Angular 中忘掉“像使用 jQuery 那样编码”的想法,这种做法行不通。


我找不到“of”的文档。 - Mangesh
@Mangesh 这个语法不是特定于Angular的,而是新的ECMAScript标准。你可以在这里阅读相关信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of - Roberc
3
对于大型数组,这种方法的性能更好,因为它在找到第一个匹配项后就会停止搜索,无需遍历每个元素。 - hkong
@Mangesh:https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html#forof-vs-forin-statements - Kunal
1
不错!对我来说比.forEach更好。即使这并没有直接回答问题。 - Camille
3
只是补充一下,始终优先使用 const 而不是 let。你不会想在这里给 a 赋一个新值。 - Guilherme Taffarel Bergamin

52

无法正常从forEach()中断。

如果您希望在中断循环时返回false,可以使用 Array.every()

如果您想返回true,则可以使用 Array.some()

this.tab.committee.ratings.every(element => {

  const _fo = this.isEmptyOrNull(element.ratings.finalOutcome.finaloutlook);
  const _foreign = this.isEmptyOrNull(element.ratings.finalOutcome.foreign);
  const _local = this.isEmptyOrNull(element.ratings.finalOutcome.local);
  const _tally = element.ratings.finalOutcome.voteTally.maj + element.ratings.finalOutcome.voteTally.dis;

  if (_fo == false && _foreign == false && _local == false) {
    if (_tally > 0) {
      **return count = false;**
    }
  } else {
    if (_tally < 0) {
      **return count = false;**
    }
  }
});

10
你无法“打破”它,因为break指令在技术上不在循环中。解决方案?只需使用普通的for循环即可。没有人会嘲笑你。

3
我认为更好的解决方案是使用for循环。使用for循环可以在找到值并跳出循环时返回该值。这是更简洁的解决方案。
for (element of this.tab.committee.ratings) {
// and here you use your element, when you return a values it stops the cycle

if (element === something){
 return element;
 }
}

-2

const blocks = document.querySelectorAll('.block');
var breakMe = false;

blocks.forEach((block, i) => {
    if(breakMe == false) {
        /*code that you want*/ 
        if(i < 2) {
            block.style.background = 'red';
        } else if(i != 4) {
            block.style.background = 'blue';
        } else if(i == 4) {
            breakMe = true;
            /*change breackMe to true if you want to breack forEach*/
        }
    }

})
<!DOCTYPE html>
  <html lang="en">
  <body>
    <div id="container">
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>      
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
    </div>
  </body>
  </html>


-3

你可以使用try-catch语句来中断foreach循环

try {
  arr.forEach((item:any) => {
    if(item === '2') {
      throw "break";
    }
    console.log('Item ID: ', item);
  });  
} catch(e) {
  console.log('Warn Error',e);
}

1
不要使用异常来中断循环,这样太昂贵了而且异常的目的也不是用于此。只需使用常规的for...循环或arr.find()来实现即可。 - Nikola Svitlica

-21

只需写上return false;,程序就会停止。


13
除非抛出异常,否则无法停止或中断forEach()循环。如果需要这样的行为,则forEach()方法不是正确的工具。 - user310988

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接