2.11배열 만들기
자바스크립트에서 배열 만드는법 정리
TL;DR
추억의 쪽지 시험
자바스크립트에서 배열을 만드는 방법은 여러가지가 있는데 때론 헷갈리고, 특히 중첩 배열을 만들때 종종 헷갈려서 큰 문제를 발생시킬 수도 있다. 이번 포스팅에서 자주 쓰이는 패턴들을 비교/정리해보자.
1. new Array()
new Array()
또는 Array()
는 숫자 하나를 넣으면 길이 지정으로 해석되고, 두개 이상 넣으면 요소 배열로 해석되어, 적기는 간편하지만 의미가 모호해질 수 있다.
javascriptnew Array(length); array(length); new Array(1, 2, 3, 4, 5);
따라서 만약에 크기가 정해진 빈 배열을 만들고 싶으면 fill()
이나 map()
으로 초기화하는 것이 좋다.
javascriptarray(n).fill(0);
그런데 이 fill
은 값 자체를 넣는다. 예를 들어, 아래는 중첩 배열을 만들기에 좋은 방법이 아니다.
javascriptArray(n).fill([]); // ([], [], [])로 모든 요소가 같은 배열 객체를 참조한다! Array(n).fill(()=> []) //[[Function], [Function], [Function]] 함수 객체가 3번 들어간다!
만약에 m개의 요소를 가진 배열들을 n개 가진 배열을 굳이 Array().fill()
로 만들려면 이렇게 해야 한다.
javascriptconst array = Array(n).fill().map(()=> Array(m).fill(0));
Array(n).fill(n)
으로 우선 n칸짜리 배열을 만든 뒤, map
에서 각 칸을 교체하는 방식이다.
참고로, Array.of()
로 요소들을 포함한 배열을 만들 수도 있지만 이런 경우 []
로 리터럴하게 정의하는 편이 더 일반적이다.
javascriptArray.of(5); // [5] new Array(5); // 길이 5인 배열 [5]; // [5]
2. Array.from()
Array.from(arrayLike, [, mapFn, [, thisArg]])
가 일반적으로 쓰이는데, arrayLike 란 길이와 인덱스를 가진 객체나 iterable 객체(문자열, set, map 등)를 배열로 변환해준다.
javascriptArray.from('hello'); // ['h', 'e', 'l', 'l', 'o'] Array.from({length: 3}, (_, i) => i); // [0, 1, 2]
배열을 직접 생성하면서 동시에 매핑을 적용할 때 주로 쓰인다. 또, 배열 안의 배열을 만들때, 즉 중첩 배열(Nested Array)을 만들때도 사용한다. 알고리즘 문제를 풀다보면 사용자의 목록이 들어있는 배열이 주어지고, 해당 사용자마다 다른 사용자들과의 상호작용을 카운팅해야하는 문제를 보게 되는데 이럴 때 유용하다.
앞서 말한, m개의 요소를 가진 배열을 n개 포함한 배열을 초기화하려면,
javascriptconst array = Array.from({length : n}, () => Array(m).fill(0));
이렇게 만들면 앞서 말한 Array(n).fill([])
과는 달리 모두 다른 곳을 참조하는 서로 다른 배열들이 만들어져서 업데이트할 때도 문제가 생기지 않는다.
여기서, "아니, 안쪽은 또 왜 Array(m).fill()
이냐! 안쪽도 Array.from()
쓰는게 일관적이지 않나?"라고 할 수 있는데, 막상 써보면 가독성이 좋지가 않다. 아래를 보고 뭐가 더 나은지 생각해보자.
javascriptconst array = Array.from({length: n}, (_, i) => Array.from({length: m}, (_, j) => 0) );
3. 이외의 중첩 배열을 만드는 방법
전통적인 for
루프를 사용하는 것도 방법이다.
javascriptconst arr = []; for(let i = 0; i < n; i++){ arr.push(Array(m).fill(0)); }