javascript - 嵌套的 forEach 循环意外行为

标签 javascript arrays foreach poker

在我的扑克应用程序中,我有一组手牌,每手牌都是随机选择的具有值(value)和花色的纸牌对象的数组:

[ [ { value: 5, suit: 's' },
    { value: 4, suit: 's' },
    { value: 6, suit: 'c' },
    { value: 11, suit: 'd' },
    { value: 12, suit: 'c' } ],
  [ { value: 9, suit: 'd' },
    { value: 12, suit: 'h' },
    { value: 8, suit: 'c' },
    { value: 12, suit: 's' },
    { value: 2, suit: 's' } ],
  [ { value: 4, suit: 'h' },
    { value: 6, suit: 's' },
    { value: 10, suit: 'c' },
    { value: 3, suit: 'd' },
    { value: 7, suit: 'd' } ] ]

为了准备评估手,我想返回一个手对象数组,每个对象都有一个花色数组。所以输出将是:

[ 
  { 
    values: [5, 4, 6, 11, 12],
    suits: ['s', 's', 'c', 'd', 'c'] 
  },      
  { 
    values: [9, 12, 8, 12, 2], 
    suits: ['d', 'h', 'c', 's', 's'] 
  },
  { 
    values: [4, 6, 10, 3, 7],
    suits: ['h', 's', 'c', 'd', 'd'] 
  } 
]

我正在尝试使用嵌套的 forEach 循环来实现这一点,如下所示:

let temp = []
hands.forEach((el) => {
  temp = el
  el = {}
  el.values = []
  el.suits = []
  temp.forEach((obj) => {
    el.values.push(obj.value)
    el.suits.push(obj.suit)
    console.log(el) //expected output
  })
  console.log(el) //expected output
})
console.log(hands) //same as original

然而,正如注释所概述的那样,它的行为符合预期,直到循环结束,其中 hands 根本没有改变。我在这里缺少什么?

最佳答案

forEach 不会更改调用它的数组,它只是迭代数组,为每个元素调用一个函数。如果你想在该函数中构建一个新数组,就这样做

var newArray = [];
hands.forEach((el) => {
   var newValue = // do something here
   newArray.push(newValue);
});

我想你想做的是:

var hands = [ [ { value: 5, suit: 's' },
    { value: 4, suit: 's' },
    { value: 6, suit: 'c' },
    { value: 11, suit: 'd' },
    { value: 12, suit: 'c' } ],
  [ { value: 9, suit: 'd' },
    { value: 12, suit: 'h' },
    { value: 8, suit: 'c' },
    { value: 12, suit: 's' },
    { value: 2, suit: 's' } ],
  [ { value: 4, suit: 'h' },
    { value: 6, suit: 's' },
    { value: 10, suit: 'c' },
    { value: 3, suit: 'd' },
    { value: 7, suit: 'd' } ] ];

let newValues = []
hands.forEach((el) => {
  var temp = {values:[], suits:[]};
  el.forEach((obj) => {
    temp.values.push(obj.value)
    temp.suits.push(obj.suit)
    
  })
  newValues.push(temp);
})
console.log(newValues) // NOT same as original

有很多方法可以实现同样的事情,我能想到的最好的方法如下 - 并避免在其他答案中看到的双重 hand.map(这是非常低效的)。

var hands = [ [ { value: 5, suit: 's' },
    { value: 4, suit: 's' },
    { value: 6, suit: 'c' },
    { value: 11, suit: 'd' },
    { value: 12, suit: 'c' } ],
  [ { value: 9, suit: 'd' },
    { value: 12, suit: 'h' },
    { value: 8, suit: 'c' },
    { value: 12, suit: 's' },
    { value: 2, suit: 's' } ],
  [ { value: 4, suit: 'h' },
    { value: 6, suit: 's' },
    { value: 10, suit: 'c' },
    { value: 3, suit: 'd' },
    { value: 7, suit: 'd' } ] ];

let newValues = hands.map(h => {
      return h.reduce( (p,c) => {
            p.values.push(c.value);
            p.suits.push(c.suit);
            return p;
        },{values:[], suits:[]});
  });

console.log(newValues) // NOT same as original

关于javascript - 嵌套的 forEach 循环意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41247681/

相关文章:

javascript - 如何调用数组上的对象方法?

arrays - 在 Swift 中将时间数组从 24 小时转换为 12 小时

arrays - 使用 mongoose 将对象添加到数组

php session 购物车使用插入记录项目数量两次

c# - 为什么我们不能在 foreach 循环中更改迭代变量

javascript - 如何检查图像是否脏 PhotoEditorSDK

javascript - 如何展开 - 在 ui 网格分组中折叠行单击?

javascript - 尝试用responseText替换行的innerhtml

c - 如何在 C 中释放二维数组内存

java - 如何使用流和 lambda 转换包含简单 for 循环的 java 代码?