yunicornlab

2차원 배열 생성 시 주의할 점 본문

Coding Test

2차원 배열 생성 시 주의할 점

yunicornlab 2025. 3. 11. 23:27

문제

N x N 크기의 2차원 배열을 생성하려고 아래와 같이 코드를 작성했다.

let grid = Array.from({ length: N }).fill(
    Array.from({ length: N }).fill(0)
);

 

그런데 웬걸, grid[0][0] = 1을 했더니 모든 행의 grid[i][0]도 1로 변하는 문제가 생겼다.

문제는 fill() 메서드에 있었다.

fill()로 배열 안에 배열을 생성하면 얕은 복사가 되어 모든 행이 동일한 배열을 참조하게 되는 것이다.

 

수정

먼저 결론을 말하자면, 이런 문제가 발생되지 않기 위해 각 행을 개별적으로 생성해야한다. 

올바르게 수정한 코드는 아래와 같다.

let grid = Array.from({ length: N }, () => 
    Array.from({ length: N }).fill(0)
);

 

원인

그렇다면, 왜 이런 문제가 생기는 걸까?

원래 코드를 순서대로 살펴보면 다음과 같다.

 

  • Array.from({ length: bombs.length }).fill(0) → 길이가 bombs.length이고, 모든 요소가 0인 배열을 생성
  • fill()을 사용하여 같은 배열을 여러 번 복사 → 이게 문제의 원인!

즉, 얕은 복사로 인해 grid[0], grid[1], grid[2]가 모두 같은 배열을 가리키게 된다.

아래와 같은 느낌이 되는 것이다.

let row = [0, 0, 0];  // 하나의 배열이 생성됨
let grid = [row, row, row];  // 같은 배열(row)을 3번 채움
row[0] = 1

console.log(grid) // [[1, 0, 0], [1, 0, 0], [1, 0, 0]]

 

결론적으로, fill()을 사용하면 같은 배열을 공유하기 때문에, 한 곳을 수정하면 전부 변경되는 문제가 발생한다.

 

추가정보

다른 방법도 있다.

Array.from() + map()

let grid = Array.from({ length: N }).map(() => 
    new Array(N).fill(0)
);

 

Array.fill() + map()

let grid = new Array(N).fill().map(() => 
    new Array(N).fill(0)
);

 

for문

let grid = [];
for (let i = 0; i < N; i++) {
    grid.push(new Array(N).fill(0));
}

 

 

 

Array.prototype.fill()

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

 

Array.prototype.fill() - JavaScript | MDN

Array 인스턴스의 fill() 메서드는 배열의 인덱스 범위 내에 있는 모든 요소를 정적 값으로 변경합니다. 그리고 수정된 배열을 반환합니다.

developer.mozilla.org

 

Array.from()

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/from

 

Array.from() - JavaScript | MDN

Array.from() 정적 메서드는 순회 가능 또는 유사 배열 객체에서 얕게 복사된 새로운 Array 인스턴스를 생성합니다.

developer.mozilla.org

 

'Coding Test' 카테고리의 다른 글

시간복잡도란?  (0) 2025.03.11
취업 성공을 위한 코딩테스트 준비  (1) 2025.03.11