用`forEach`循环代替`for`循环

时间:2018-10-31 10:44:09

标签: javascript arrays loops

我正在研究将任务卡移至下一列的StateService方法。我能够编写taskMoveLeft方法,但效果很好,但是我无法使用taskMoveRight循环为forEach方法复制其功能,我只能使它与{{1} }循环。

for方法的工作示例(使用taskMoveLeft):

forEach

taskMoveLeft(id) { state.columns.forEach((column, columnIndex) => { if (state.columns[0] !== column) { if (column.cards) { column.cards.forEach((card, cardIndex) => { if (card.id === id) { if (state.columns[columnIndex - 1].cards) { // Add card to the target column card collection state.columns[columnIndex - 1].cards.push(card); } else { // Create target column card collection and add card state.columns[columnIndex - 1].cards = Array.of(); state.columns[columnIndex - 1].cards.push(card); } // Remove the card from the source column card collecion state.columns[columnIndex].cards.splice(cardIndex, 1); } }); } } }); } 方法的工作示例(使用taskMoveRight循环):

for

无法使taskMoveRight(id) { for (let i = 0; i < state.columns.length; i++) { if (state.columns[state.columns.length - 1] !== state.columns[i]) { if (state.columns[i].cards) { for (let j = 0; j < state.columns[i].cards.length; j++) { if (state.columns[i].cards[j].id === id) { if (state.columns[i + 1].cards) { // Add card to the target column card collection state.columns[i + 1].cards.push(state.columns[i].cards[j]); } else { // Create target column card collection and add card state.columns[i + 1].cards = Array.of(); state.columns[i + 1].cards.push(state.columns[i].cards[j]); } // Remove the card from the source column card collecion return state.columns[i].cards.splice(j, 1); } } } } } } 方法与taskMoveRight循环一起使用。使用此代码,卡总是移到最右列:

forEach

2 个答案:

答案 0 :(得分:0)

forEach并不是正确的工具,因为您要尽早终止循环。相反,由于您需要卡的索引,请使用findIndex。请参见***注释以及其他建议:

taskMoveRight(id) {
  for (let i = 0; i < state.columns.length; i++) {
    // *** Instead of repeating it all over
    const column = state.columns[i];
    if (state.columns[state.columns.length - 1] !== column) {
      if (column.cards) {
        // *** Find the card
        const cardIndex = column.cards.findIndex(card => card.id == id);
        // *** Get the card if found
        const card = cardIndex !== -1 && column.cards[cardIndex];
        if (card) {
            // *** Instead of repeating it
            const nextColumn = state.columns[i + 1];
            if (nextColumn.cards) {
              // Add card to the target column card collection
              nextColumn.cards.push(card);
            } else {
              // Create target column card collection and add card
              // *** Using Array.of() to create an empty array and then pushing
              // *** to it is quite round-about; instead: [card]
              nextColumn.cards = [card];
            }
            // Remove the card from the source column card collecion
            return column.cards.splice(cardIndex, 1);
        }
      }
    }
  }
}

答案 1 :(得分:0)

因为您用当前卡片修改了下一行,然后当您到达下一行时,这些卡片又被移动了。您必须迭代反向,因此您必须执行以下操作来代替.forEach((entry, i)

  array.reverse().forEach((entry, i) => {
    i = array.length - 1 - i;

但是那有点丑陋。


相反,我不是坚持使用.forEach,而是使用for循环。我将保留一组条目向右移动,这样您可以将逻辑简化为:

  let previousMove = [];

  for(const column of state.columns) {
    if(!column.cards) column.cards = [];
    let currentMove = column.cards.filter(card => card.id === id);
    column.cards = column.cards.filter(card => card.id !== id).concat(previousMove);
    previousMove = currentMove;
  }

这也可以通过reduce完成:

 state.columns.reduce((move, column) => {
    if(!column.cards) column.cards = [];
    const nextMove= coumn.cards.filter(card => card.id === id);
   column.cards = column.cards.filter(card => card.id !== id).concat(move);
   return nextMove;
 }, []);

要移动左,只需使用reduceRight而不是reduce