Reputation: 2791
I'd love an explanation as to why the result of this function don't match my expectation.
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
}()
The result, once the promise is resolved returns:
[
{ f: 'a', number: 2 },
{ f: 'a', number: 2 },
{ f: 'b', number: 2 },
{ f: 'b', number: 2 }
]
But, my expectation is that it would return:
[
{ f: 'a', number: 1 },
{ f: 'a', number: 2 },
{ f: 'b', number: 1 },
{ f: 'b', number: 2 }
]
One of the things that puzzles me the most is that if I console.log
the value of object just before I push, it logs out each of the objects in my expected result.
Upvotes: 5
Views: 13882
Reputation: 192287
Use Array.flatMap()
to iterate the objects
, with a nested Array.map()
to iterate the numbers
and return an array of new objects with the relevant number. The flatMap will flatten the arrays produced by the map to a single array:
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);
Old answer:
Use nested Array#map to iterate the objects
and the numbers
, and Object#assign to create new objects that include the relevant number. Flatten resulting nested arrays by using the spread syntax in 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);
Upvotes: 2
Reputation: 1703
@Nenad is correct. You can also do it with reduce and map.
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;
}, []);
Upvotes: 0
Reputation: 122087
Because objects are passed by reference and you are modifying original object, instead you can push new object.
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)
Upvotes: 8