HOWTO · JavaScript

JavaScript 2D 어레이

이 튜토리얼에서는 JavaScript에서 2 차원 배열을 선언하는 방법을 소개합니다.

이 페이지의 내용

JavaScript의 2차원 배열은 요소가 행 배열인 배열입니다. 값이 정해져 있다면 중첩 배열 리터럴을 사용하고, 크기나 값이 데이터에 따라 달라진다면 반복문, Array.from(), 또는 Array.prototype.map()으로 각각 별도의 행을 만들 수 있습니다. 셀을 읽을 때는 grid[rowIndex][columnIndex]처럼 인덱스 두 개를 사용합니다.

JavaScript의 2차원 배열이란?

JavaScript에는 별도의 2차원 배열 타입이 없습니다. 격자 형태의 데이터는 배열의 배열로 표현합니다. 바깥 배열에는 행이 들어 있고, 각 행에는 셀이 들어 있습니다. 이 구조는 행렬, 게임 보드 또는 그 밖의 행과 열로 이루어진 데이터를 나타낼 수 있습니다. 행마다 길이가 다를 수 있으므로, 직사각형 모양이 보장되지 않는다면 각 행의 길이를 확인하세요.

배열 인덱스는 0부터 시작합니다. grid[1][2]에서 1은 두 번째 행을, 2는 그 행의 세 번째 셀을 가리킵니다. 행을 만들고 셀을 채우는 일은 별개의 단계입니다. 새로 할당한 배열에는 초기화되지 않은 슬롯이 있을 수 있으며, 이는 null로 설정된 셀과 다릅니다.

중첩 배열 리터럴로 2차원 배열 만들기

값이 정해진 고정 크기 격자라면 각 행을 내부 배열로 작성하세요.

const grid = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

console.log(grid[0][1]);

각 내부 배열은 서로 독립된 행입니다. grid[0][1]은 값 2를 가리킵니다. 첫 번째 인덱스는 행을 선택하고, 두 번째 인덱스는 그 행 안의 셀을 선택합니다. 필요한 데이터가 모두 준비되어 있을 때는 리터럴 표기법을 사용하면 편리합니다.

반복문으로 2차원 배열 만들기

크기나 셀 값이 실행 중에 결정된다면 중첩 반복문을 사용하세요. 바깥 반복이 한 번 실행될 때마다 새 행을 할당한 다음, 각 셀에 값을 넣습니다.

const rows = 3;
const columns = 3;
const grid = [];

for (let row = 0; row < rows; row++) {
  grid[row] = [];
  for (let column = 0; column < columns; column++) {
    grid[row][column] = row * columns + column + 1;
  }
}

console.log(grid);

바깥 반복문은 서로 독립된 행 세 개를 만듭니다. 안쪽 반복문은 각 행을 1부터 9까지의 값으로 채웁니다. 셀을 기본값으로 시작하려면 안쪽 반복문에서 grid[row][column] = 0처럼 값을 할당하세요.

변경 가능한 행을 만들 때는 Array(rows).fill(Array(columns).fill(0))을 사용하지 마세요. fill()은 같은 행 참조를 반복하므로, 한 행을 바꾸면 모든 행의 해당 열에서 같은 변경이 보입니다. 대신 바깥 반복이 실행될 때마다 새 행을 만드세요.

Array.from()으로 2차원 배열 만들기

Array.from()을 사용하면 바깥 배열과 각 인덱스에 해당하는 새 행을 만들 수 있습니다. 매핑 콜백에는 현재 인덱스가 전달되므로, 행과 열을 기준으로 각 셀의 값을 계산할 수 있습니다.

const rows = 3;
const columns = 3;
const grid = Array.from({ length: rows }, (_, row) =>
  Array.from({ length: columns }, (_, column) => row * columns + column + 1)
);

console.log(grid);

바깥쪽 호출은 행 세 개를 만들고, 안쪽 호출은 각 행을 값 세 개로 만들어 채웁니다. 안쪽 Array.from()은 바깥쪽 인덱스마다 한 번씩 실행되므로 행은 각각 별도의 배열입니다. 모든 셀을 0으로 시작하려면 안쪽 호출에 Array.from({ length: columns }, () => 0)을 사용하세요.

Array.prototype.map()으로 2차원 배열 만들기

map()은 배열에 이미 있는 요소를 새 배열로 변환합니다. 콜백이 모든 행에 대해 실행되도록 값이 들어 있는 슬롯으로 시작하세요. new Array(rows)만으로 만든 배열에는 희소 슬롯이 생기며, map()은 이러한 슬롯을 건너뜁니다.

const rows = 3;
const columns = 3;
const grid = Array.from({ length: rows }, (_, row) => row).map(row =>
  Array.from({ length: columns }, (_, column) => row * columns + column + 1)
);

console.log(grid);

여기서는 먼저 Array.from()으로 행 인덱스가 채워진 시퀀스를 만든 다음, Array.prototype.map()으로 각 인덱스마다 독립된 새 행을 만듭니다. 콜백에서 기본값으로 채운 행을 반환할 수도 있습니다. 예를 들어 Array.from({ length: columns }, () => 0)을 사용할 수 있습니다.

2차원 배열의 값 초기화와 접근

셀을 읽으려면 grid[row][column]을 사용하고, 값을 바꾸려면 grid[1][2] = 42처럼 같은 인덱스에 값을 할당하세요. 행이 세 개이고 열이 네 개인 배열에서 유효한 행 인덱스는 0부터 2까지이며, 유효한 열 인덱스는 0부터 3까지입니다. JavaScript는 배열을 직사각형 모양으로 강제하지 않으므로, 각 행의 길이에 따라 사용할 수 있는 열 인덱스가 달라집니다.

격자의 모든 셀을 같은 시작값으로 초기화하려면 행마다 새 배열을 만드세요. 예를 들어 Array.from({ length: rows }, () => Array.from({ length: columns }, () => 0))은 각 셀이 0으로 설정된 독립 행을 만듭니다. 이는 희소 슬롯이 있는 new Array(rows)나 fill()로 하나의 내부 배열을 반복하는 방식과 다릅니다.

값이 이미 정해져 있다면 리터럴을, 배열을 만드는 과정을 명시적으로 제어해야 한다면 반복문을, 행과 셀을 생성해야 한다면 Array.from()을 사용하세요. 이미 값이 채워진 시퀀스를 변환할 때는 Array.prototype.map()을 사용할 수 있습니다. 네 가지 방법 모두 일반적인 중첩 배열을 만듭니다. 셀을 읽고 바꿀 때는 행 인덱스 다음에 열 인덱스를 지정하세요.