본문 바로가기
JS

2차배열에서 한 값을 변경할때 전체 줄이 바뀌는 문제 해결법

by limew 2023. 7. 29.

2차배열을 생성할때 이렇게 생성하고 한 값을 변경했는데 내가 바꾸지도 않은 전체 줄의 값이 바꼈다

const newArr =  new Array(len).fill(new Array(len).fill(null));
newArr[0][0] = 5;
console.log(newArr)

출력값
[
  [ 5, 0, 0, 0, 0 ],
  [ 5, 0, 0, 0, 0 ],
  [ 5, 0, 0, 0, 0 ],
  [ 5, 0, 0, 0, 0 ],
  [ 5, 0, 0, 0, 0 ]
]

내가 예상한 값은 [0][0]만 5로 변하는 건데 전체 행 줄의 값이 바꼈다.

 

문제의 이유를 찾아보니

각 행이 실제로 메모리에 있는 하나의 리스트를 가리키는 참조(reference)로 구현되어 있기 때문에 발생

 

 

해결법

해당 행을 수정하기 전에 해당 행의 복사본을 만든뒤에 수정해야한다
// 지정된 행과 열의 2D 배열을 생성하는 함수
function create2DArray(rows, cols) {
  return Array.from({ length: rows }, () => Array(cols).fill(0));
}

// 2차배열 생성방법2
// const newArr =  new Array(5).fill(new Array(5).fill(null));

// 전체 줄이 영향을 받지 않고 2D 배열에서 특정 값을 수정하는 함수
function modifyValue(array, row, col, newValue) {
  // 해당 행을 수정하기 전에 복사본을 만듭니다.
  array[row] = array[row].slice();
  array[row][col] = newValue;
}

// 사용 예시:
const rows = 3;
const cols = 4;
const myArray = create2DArray(rows, cols);

// 수정 전
console.log(myArray);

modifyValue(myArray, 1, 2, 42);

// 수정 후
console.log(myArray);

 

 

 

 

예)

const len = 5;
const newArr = new Array(len).fill(new Array(len).fill(null));

// 수정하기 전에 복사
// 복사법 Array.from, spread
newArr[0] = Array.from(newArr[0]);
newArr[0][0] = 1;
console.log(newArr);

[
  [ 1, null, null, null, null ],   
  [ null, null, null, null, null ],
  [ null, null, null, null, null ],
  [ null, null, null, null, null ],
  [ null, null, null, null, null ] 
]