使用嵌套的forEach循环将对象推入数组

5
我很愿意解释为什么这个函数的结果与我的期望不一致。
const numbers = [ 1, 2 ]
const objects = [{f: 'a'}, {f: 'b'}]

async function(domain) {
  let matrix = []
  objects.forEach((object) => {
    numbers.forEach((number) => {
      object.number = number
      matrix.push(object)
    })
  }) 
  return matrix
}()

实际结果

一旦承诺被解决,返回结果如下:

[ 
  { f: 'a', number: 2 },
  { f: 'a', number: 2 },
  { f: 'b', number: 2 },
  { f: 'b', number: 2 } 
] 

预期结果

但是,我预期的结果是它将返回:

[ 
  { f: 'a', number: 1 },
  { f: 'a', number: 2 },
  { f: 'b', number: 1 },
  { f: 'b', number: 2 } 
] 

有一件事情让我感到困惑,就是如果在我推送之前使用console.log记录对象的值,它会记录下我预期结果中的每个对象。


为什么在函数中没有异步操作,也没有使用await时,你要将其定义为“async”? - trincot
糟糕,这是因为我从另一段使用了await的代码中提取了问题。我可以删除它并重新表述。 - counterbeing
3个回答

8

因为对象是按引用传递的,你正在修改原始对象,所以你可以推入一个新的对象。

const numbers = [ 1, 2 ]
const objects = [{f: 'a'}, {f: 'b'}]

let matrix = []
objects.forEach((object) => {
  numbers.forEach((number) => {
    matrix.push({...object, number})
  })
})

console.log(matrix)


可能是对象中的rest语法,尝试使用以下代码:matrix.push(Object.assign({}, object, {number})) - Nenad Vracar
@HermanLauenstein 可能对象展开尚未实现。请使用 Object.assign() 然后 matrix.push(Object.assign({}, object, {number})) - Arup Rakshit
对我来说,这并不重要,因为我的目标环境是Node,并且需要进行一些转译。我应该打上某些标签以使其明显吗?我有点觉得这都属于ES6标签。 - counterbeing

2
使用 Array.flatMap() 来迭代 objects,嵌套使用 Array.map() 迭代 numbers 并返回一个包含相关数字的新对象数组。flatMap 将 map 产生的数组展开为单个数组:

const numbers = [ 1, 2 ]
const objects = [{f: 'a'}, {f: 'b'}]

const matrix = objects.flatMap(o => // map the objects and flatten
  numbers.map( // map the numbers
    number => ({ ...o, number }) // return a new object with the number
  )
);

console.log(matrix);

新回答:

使用嵌套的Array#map函数遍历objectsnumbers,并使用Object#assign函数创建包含相关数字的新对象。通过在Array#concat中使用展开语法来展开结果嵌套数组:

const numbers = [ 1, 2 ]
const objects = [{f: 'a'}, {f: 'b'}]

const matrix = [].concat(... // flatten the nested arrays
  objects.map((o) => // map the objects
    numbers.map( // map the numbers
      (number) => Object.assign({}, o, { number }) // return a new object with the number
    )
  ));

console.log(matrix);


0

@Nenad 是正确的。你也可以使用 reducemap 来完成。

const numbers = [ 1, 2 ];
const objects = [{f: 'a'}, {f: 'b'}];

const matrix = numbers.reduce((acc, nxt) => {
 const numberedObjs = objects.map(obj => ({...obj, number:nxt}));
 acc.push(...numberedObjs);
 return acc;
}, []);


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