Back

Technologies:

javascriptjavascript
avatar
Tolerim
13 days ago

How can I use array methods in JavaScript?

This question already has answers here:
Array.prototype.fill() with object passes reference and not new instance (7 answers) Closed 2 hours ago.
I'd like to modify a two-dimensional array while retaining the two-dimensional aspect, but with different elements. I'm going to share the code with you to save time:

const rotateTetromino = () => {
        const rotatedTetromino = [];
        for (let i = 0; i < tetromino.length; i++) {
            rotatedTetromino.push([]);
        }
        let k = 0;
        for (let i = tetromino.length - 1; i >= 0; i--) {
            for (let j = 0; j < tetromino[i].length; j++) {
                rotatedTetromino[j][k] = tetromino[i][j];
            }
            k++;
        }
        return rotatedTetromino;
};
For this input:

let tetromino = [
        [0, 1, 0],
        [0, 1, 0],
        [1, 1, 0],
    ];
I receive the output:

[[1, 0, 0],
    [1, 1, 1],
    [0, 0, 0]]
This is suitable for my needs because it allows me to rotate Tetrominos for a game of Tetris. However, when I try the same function with the fill method to rotate the Tetromino, I get an incorrect array. Here's the function:

const rotateTetromino = () => {
        const rotatedTetromino = new Array(tetromino.length).fill([]);
        let k = 0;
        for (let i = tetromino.length - 1; i >= 0; i--) {
            for (let j = 0; j < tetromino[i].length; j++) {
                rotatedTetromino[j][k] = tetromino[i][j];
            }
            k++;
        }
        return rotatedTetromino;
};
For the same initial rotatedTetromino, the for loop works in different ways. Why is that?

let tetromino = [
        [0, 1, 0],
        [0, 1, 0],
        [1, 1, 0],
    ];
Answers(2)
avatar
Vogi
11 days ago
Verified Answer
The reason why the fill method in JavaScript passes reference instead of a new instance is because the fill method fills the array with the same reference. In other words, it fills the array with the same object instance. So when you modify one element of the array, you are actually modifying all elements of the array that reference that object instance. In your case, when you use new Array(tetromino.length).fill([]), you are filling the array with the same empty array instance. So when you modify one element of the rotatedTetromino array, you are actually modifying all elements of the rotatedTetromino array that reference that empty array instance. To fix this issue, you can use Array.from() instead of fill(). Here's how:
This will create a new instance of an empty array for each element in the rotatedTetromino array. I hope this helps! Let me know if you have any other questions.

Sources

Classes - JavaScript | MDN - Mozilla Developervariables - javascript pass object as reference - Stack OverflowMethod References (The Java™ Tutorials - Oraclejavascript - Array.fill(Array) creates copies by references not by ...javascript - How do I use array.fill for creating an array of objects ...Array.prototype.fill() - JavaScript | MDN - Mozilla Developer
avatar
Tolerim
13 days ago
The reason for the difference in results between the two versions of the rotateTetromino function is due to the behavior of Array.prototype.fill() method. When an object is passed as the argument to fill(), a reference to that object is stored in each element of the array, instead of creating a new object for each element. In the first version of the function, each time a new empty array is pushed to the rotatedTetromino array, a new instance of an empty array is created. Then, each element is individually assigned a new value without affecting the other elements. In the second version of the function, a new array object is created with new Array(tetromino.length). When fill([]) is called, a reference to the same empty array instance is stored in each element of the array. As a result, when values are assigned to rotatedTetromino[j][k], the same object is being modified for each element, resulting in unexpected behavior. To fix this issue, you can use Array.prototype.map() instead of fill([]) to create a new instance of an array for each element in the array. Here is an updated version of the rotateTetromino function using map():
const rotateTetromino = () => {
  const rotatedTetromino = new Array(tetromino.length).fill(null).map(() => []);
  let k = 0;
  for (let i = tetromino.length - 1; i >= 0; i--) {
    for (let j = 0; j < tetromino[i].length; j++) {
      rotatedTetromino[j][k] = tetromino[i][j];
    }
    k++;
  }
  return rotatedTetromino;
};
In this updated version, new Array(tetromino.length).fill(null) creates an array with null values for each element, and then map(() => []) creates a new array for each element using the arrow function.
;