JS, difference in array matrix and forEach behavior

后端 未结 3 1597
太阳男子
太阳男子 2021-01-19 19:53

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

相关标签:
3条回答
  • 2021-01-19 20:11

    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))

    0 讨论(0)
  • 2021-01-19 20:31
    // your example is roughly equivalent to this.
    const innerArray = new Array(n).fill(0);
    const mat = new Array(n).fill(innerArray);
    
    (mat[0] === mat[1] === innerArray) === true;
    

    there is only 1 nested array, not n times array.

    0 讨论(0)
  • 2021-01-19 20:32

    It's because Array is a reference type. When you do

    new Array(n).fill(new Array(n).fill(0))

    first the inner new Array(n).fill(0) makes an array size n filled with 0; next the outer Array(n).fill creates an array filled with n references to that inner array.

    It doesn't create n inner arrays, just n references to the same array. So when you change an element of that inner array, all the references in the outer array will reflect the change since they all point to the same object.

    0 讨论(0)
提交回复
热议问题