Не удалось установить значение ячейки матрицы - PullRequest
0 голосов
/ 27 октября 2018

Почему, когда я делаю это:

let matrix = Array(3).fill(new Array(3).fill(0));
matrix[0][1] = 1

Я бы ожидал, что матрица будет:

    [ [0,1,0],
      [0,0,0],
      [0,0,0]  ]

Но вместо этого матрица выглядит так:

   [ [0,1,0],
     [0,1,0],
     [0,1,0] ]

Таким образом, он устанавливает весь столбец, а не только ячейку. Я чувствую, что скучаю по очень важной части языка здесь.

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 27 октября 2018

Поскольку вы используете одну и ту же ссылку в памяти для всех индексов.

Представьте, что это память, индексы указывают на одно и то же значение в памяти, поэтому каждое изменение в конкретнойindex будет изменять это значение

    new Array(3).fill(0)     Matrix
    +---------+           +-----------+
    | [0,0,0] | <--+------|   Index 0 |
    +---------+    |      +-----------+
          ^        +------|   Index 1 |
          |               +-----------+
          +---------------|   Index 2 |
                          +-----------+

Создать новый массив для каждого индекса

    {length: 3}, () => Array(3).fill(0)     Matrix
    +---------+                         +-----------+
    | [0,0,0] | <-----------------------|   Index 0 |
    +---------+                         +-----------+
    | [0,0,0] | <-----------------------|   Index 1 |
    +---------+                         +-----------+
    | [0,0,0] | <-----------------------|   Index 2 |
    +---------+                         +-----------+

let matrix = Array.from({length: 3}, () => Array(3).fill(0));
matrix[0][1] = 1;

console.log(matrix);
0 голосов
/ 27 октября 2018

Поскольку индексы «внешнего» массива ссылаются только на один массив, вы также можете изначально fill исходный массив с нулями, а затем использовать map для создания новых массивов для каждого индекса:

let matrix = Array(3).fill(0).map(n => new Array(3).fill(0));

matrix[0][1] = 1;
console.log(matrix);
0 голосов
/ 27 октября 2018

Когда вы используете .fill и передаете его не примитивно (например, объект или массив), в памяти будет только один из этих реальных объектов; массив будет заполнен тремя ссылками на один и тот же объект, поэтому, когда один индекс мутирует, все они делают. Если вы хотите заполнить массив отдельными объектами, вам придется явно создавать их на каждой итерации создания нового массива, что вы можете сделать с Array.from:

const matrix = Array.from(
  { length: 3 },
  () => new Array(3).fill(0)
);
matrix[0][1] = 1;
console.log(matrix);

Используйте .fill только с примитивами, или когда вы действительно уверены, что 1016 *, вам нужно несколько ссылок на один и тот же объект в одном массиве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...