При копировании массива(матрицы) и в ходе модификации КОПИИ меняется исходный массив, передающийся функции, как аргумент

166
10 декабря 2019, 09:00

Требовалось воссоздать принцип игры Сапер

matrix = [[true, false, false],
          [false, true, false],
          [false, false, false]]

function minesweeper(m) {
   let result = m.slice();
   for(let i = 0; i < m.length; i++){
      for(let j = 0; j < m[i].length; j++){
        result[i][j] = m.slice(Math.max(i-1,0),i+2).map((row => row.slice(Math.max(j-1,0), j+2).reduce((s,el) =>
        s + el)).reduce((sum, n)=> sum + n,0) - m[i][j];
    }
}
return result;
}
minesweeper([[false,true,true,false], 
             [true,true,false,true], 
             [false,false,true,false]])
//Ожидаемый результат: [[3,3,3,2],
//                      [2,4,5,2],
//                      [2,3,2,2]].
//А по сути получаем: [[3,6,8,9],
//                     [10,28,53,71],
//                     [38,130,282,406]]

Проблема решается, если не копировать исходный массив, а создать новый...

function minesweeper(m) {  
   let result = [];
   for(let i = 0; i < m.length; i++){
      result.push([]);
      for(let j = 0; j < m[i].length; j++){
         result[i][j] = m.slice(Math.max(i-1,0),i+2).map(row => row.slice(Math.max(j-1,0), j+2).reduce((s,el) =>
         s + el)).reduce((sum, n)=> sum + n,0) - m[i][j];
      }
   }
return result;
}

Пожалуйста, объясните кто-нибудь, почему в процессе хождения интерпретатора по циклу меняется исходный массив тоже? Ведь я явно работаю с его копией...=(

Answer 1

Вы работаете с неполной копией. У вас массив массивов и вы создали копию только "внешнего" массива.

Надо скопировать и вложенные массивы тоже.

function minesweeper(m) { 
  let result = m.map(_m => _m.slice()); // копируем воженные массивы 
  for (let i = 0; i < m.length; i++) { 
    result.push([]); 
    for (let j = 0; j < m[i].length; j++) { 
      result[i][j] = m.slice(Math.max(i - 1, 0), i + 2).map(row => row.slice(Math.max(j - 1, 0), j + 2).reduce((s, el) => 
        s + el)).reduce((sum, n) => sum + n, 0) - m[i][j]; 
    } 
  } 
  return result; 
} 
let a = [ 
  [false, true, true, false], 
  [true, true, false, true], 
  [false, false, true, false] 
]; 
 
let b = minesweeper(a); 
 
console.log(a, b);

READ ALSO
vue js скрыть Input при клике на кнопку

vue js скрыть Input при клике на кнопку

Как можно скрыть input при клике на кнопку? Скрыть, не используя стили (навроде documentgetElem

111
Как сравнить массивы объектов по полю?

Как сравнить массивы объектов по полю?

Есть 2 массива rows_1, rows_2 и есть функция которая ищет совпадение полей:

148