sungyup's.

Web_Miscellaneous / JavaScript / 2.11 배열 만들기

2.11배열 만들기

자바스크립트에서 배열 만드는법 정리

TL;DR

추억의 쪽지 시험

자바스크립트에서 배열을 만드는 방법은 여러가지가 있는데 때론 헷갈리고, 특히 중첩 배열을 만들때 종종 헷갈려서 큰 문제를 발생시킬 수도 있다. 이번 포스팅에서 자주 쓰이는 패턴들을 비교/정리해보자.

1. new Array()

new Array()또는 Array()는 숫자 하나를 넣으면 길이 지정으로 해석되고, 두개 이상 넣으면 요소 배열로 해석되어, 적기는 간편하지만 의미가 모호해질 수 있다.

javascript
new Array(length); array(length); new Array(1, 2, 3, 4, 5);

따라서 만약에 크기가 정해진 빈 배열을 만들고 싶으면 fill()이나 map()으로 초기화하는 것이 좋다.

javascript
array(n).fill(0);

그런데 이 fill값 자체를 넣는다. 예를 들어, 아래는 중첩 배열을 만들기에 좋은 방법이 아니다.

javascript
Array(n).fill([]); // ([], [], [])로 모든 요소가 같은 배열 객체를 참조한다! Array(n).fill(()=> []) //[[Function], [Function], [Function]] 함수 객체가 3번 들어간다!

만약에 m개의 요소를 가진 배열들을 n개 가진 배열을 굳이 Array().fill()로 만들려면 이렇게 해야 한다.

javascript
const array = Array(n).fill().map(()=> Array(m).fill(0));

Array(n).fill(n)으로 우선 n칸짜리 배열을 만든 뒤, map에서 각 칸을 교체하는 방식이다.

참고로, Array.of()로 요소들을 포함한 배열을 만들 수도 있지만 이런 경우 []로 리터럴하게 정의하는 편이 더 일반적이다.

javascript
Array.of(5); // [5] new Array(5); // 길이 5인 배열 [5]; // [5]

2. Array.from()

Array.from(arrayLike, [, mapFn, [, thisArg]])가 일반적으로 쓰이는데, arrayLike 란 길이와 인덱스를 가진 객체나 iterable 객체(문자열, set, map 등)를 배열로 변환해준다.

javascript
Array.from('hello'); // ['h', 'e', 'l', 'l', 'o'] Array.from({length: 3}, (_, i) => i); // [0, 1, 2]

배열을 직접 생성하면서 동시에 매핑을 적용할 때 주로 쓰인다. 또, 배열 안의 배열을 만들때, 즉 중첩 배열(Nested Array)을 만들때도 사용한다. 알고리즘 문제를 풀다보면 사용자의 목록이 들어있는 배열이 주어지고, 해당 사용자마다 다른 사용자들과의 상호작용을 카운팅해야하는 문제를 보게 되는데 이럴 때 유용하다.

앞서 말한, m개의 요소를 가진 배열을 n개 포함한 배열을 초기화하려면,

javascript
const array = Array.from({length : n}, () => Array(m).fill(0));

이렇게 만들면 앞서 말한 Array(n).fill([])과는 달리 모두 다른 곳을 참조하는 서로 다른 배열들이 만들어져서 업데이트할 때도 문제가 생기지 않는다.

여기서, "아니, 안쪽은 또 왜 Array(m).fill()이냐! 안쪽도 Array.from()쓰는게 일관적이지 않나?"라고 할 수 있는데, 막상 써보면 가독성이 좋지가 않다. 아래를 보고 뭐가 더 나은지 생각해보자.

javascript
const array = Array.from({length: n}, (_, i) => Array.from({length: m}, (_, j) => 0) );

3. 이외의 중첩 배열을 만드는 방법

전통적인 for루프를 사용하는 것도 방법이다.

javascript
const arr = []; for(let i = 0; i < n; i++){ arr.push(Array(m).fill(0)); }