I was doing some training tasks for my JS course and I got one where you must implement a function that takes a positive integer (n) and returns a matrix like the one below
The code in question is equivalent to this:
let n = 5
let innerArr = new Array(n).fill(0)
function getIdentityMatrix(n) {
const mat = new Array(n).fill(innerArr);
return mat.map((row, index) => {
row[index] = 1;
return row;
});
}
console.log(getIdentityMatrix(n))
Because you are using fill
you are basically filling that mat
array with references to the innerArr
(which you can see clearly from the above console output)
.
Then you do row[index] = 1
for each i which is changing the same values (at i index) of the same array.
Now your working example ... which could be written in a shorter form as:
const getIdentityMatrix = (n) =>
[...Array(n)].map((row, index) => {
row = Array(n).fill(0)
row[index] = 1
return row
})
console.log(getIdentityMatrix(3))
Clearly maps
over a newly created and then spreaded array of n
but then overwrites each element with an entirely new array reference.
Since that reference is brand new modifying it with row[index] = 1
produces the expected behavior when we return the x
from the map.
Another way to achieve this in one line is via map
, Object.assign and Object.values like this:
const gm = (n) => [...Array(n)].map((x,i) =>
Object.values(Object.assign(Object.assign({}, Array(n).fill(0)), {[i]:1})))
console.log(gm(3))