Неожиданный результат с 2d массивом - изменен весь столбец - PullRequest
0 голосов
/ 19 июня 2020

Учитывая матрицу 3x3, я хочу установить элемент в первой строке, третьем столбце на true.

Я ожидал бы, что m[0][2] = true сделает это, но это не так. Он устанавливает для всего столбца значение true!

Мой код для создания массива и установки значения ниже. Что вызвало такое поведение?

const size = 3;

const m = Array(size).fill(Array(size).fill(false))

console.log(m); 
/* [[false, false, false], 
    [false, false, false], 
    [false, false, false]]
*/

m[0][2] = true;

console.log(m);
/*
   [[false, false, true], 
    [false, false, true], 
    [false, false, true]]
*/

Ответы [ 2 ]

3 голосов
/ 19 июня 2020

Вы заполняете первый массив одним и тем же массивом в каждой точке.

let array1 = [false, false, false];
let array2 = array1;
array1[2] = true;
console.log(array2);

Используйте Array.from

let size = 3;
let m = Array.from({ length: size }, _ => Array.from({ length: size }, _ => false));
console.log(m);
m[0][2] = true;
console.log(m);

Таким образом, у вас будет другой экземпляр массива в каждом слоте массива верхнего уровня.

Вы можете использовать Array.fill в функции как false - это объект значения, а не объект ссылки.

let size = 3;
let m = Array.from({ length: size }, _ => Array(size).fill(false));
console.log(m);
m[0][2] = true;
console.log(m);
0 голосов
/ 19 июня 2020

7 способов создания 2D-матриц в JavaScript:

Один лайнер:

const size = 3;
const val = null;

const m1 = Array(size).fill(Array(size).fill(val)); // issue: rows are all the same.
const m2 = Array(size).fill([...Array(size).fill(val)]); // issue: rows are the same;

const m3 = Array(size).fill().map(_ => Array(size).fill(val));
const m4 = Array.from(Array(size), _ => Array(size).fill(val));

const m5 = Array.from({length: size}, _ => Array.from({length: size}, _ => val))

Все они будут создавать матрицы размера x. Однако использование Array.fill напрямую создаст копии по ссылке, а не по значению (например, m1 и m2). Вы можете использовать Array.fill внутри функции сопоставления, чтобы исправить проблему (например, m3, m4 и m7). Наконец, вы можете создавать матрицы, используя Array.from дважды.

Есть еще 2 способа создания матриц, но не такие элегантные.

Использование для циклов:

const m6 = [];
for(let i = 0; i < size; i++) {
    m6[i] = [];
    for(let j = 0; j < size; j++) {
        m6[i][j] = val;
    }
}

const m7 = Array(size);
for(let i = 0; i < m7.length; i++) {
    m7[i] = Array(size).fill(val);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...