[Javascript] 중첩 배열을 1차원 배열로 바꾸는 더 나은 방법들
자바스크립트는 다차원 배열이 없기 때문에 배열을 중첩해서 다차원 배열을 표현해야 합니다.
경우에 따라서는 중첩 배열을 중첩되지 않은 1차원 배열로 재 가공을 해야 할 필요가 있는데, 이때 우리가 일반적으로 사용하는 방법이 다음처럼 함수를 사용해서 배열 요소들을 순차적으로 합쳐나가는 방식입니다.
배열의 내장 함수가 2개 등장합니다.
reduce() | reduce() 함수의 첫 번째 인자로 누적 처리용 콜백 함수를 넘겨서 모든 배열 요소에 대해 누적 처리를 한 결과값을 받는 함수입니다. 배열 전체 요소의 합, 평균값 등을 얻을 때 유용합니다. 최종적으로 결과 값을 한 개 받지만, 결과 값이 꼭 프리미티브 값일 필요는 없고, 객체나 배열일 수도 있습니다. 예) [].reduce((prevAccumul, arrItem)=>{return prevAccumul+arrItem}); |
concat() | 1개 이상의 배열을 인자로 받아서 합쳐진 1개의 새 배열을 반환합니다. 예) const arr3 = arr1.concat(arr2); |
내장 배열 함수들을 이용해 중첩 배열을 1차원 배열로 변환하는 방법은 다음과 같습니다.
누적 결과를 반환하는 reduce() 함수로 이전 결과(배열)에 현재 요소(중첩 배열이므로 여기서는 현재 배열의 요소가 배열이 됨)를 concat() 함수를 이용해 하나의 배열로 합치게 됩니다.
그리고 최종적으로는 중첩 하위 배열들이 합쳐진 하나의 1차원 배열을 결과로 반환하게 됩니다.
let array = [
["abc", "def"],
["ghi", "xyz"]
];
let newArray = array.reduce(function(prev, next) {
return prev.concat(next);
});// return ['abc', 'def', 'ghi', 'xyz']
reduce() 함수는 리듀서(reducer)라고 합니다.
배열을 1차원 배열로 합치면서 후처리를 추가로 할 수도 있기 때문에 단순히 배열을 합치는 용도만으로 한정되지는 않습니다. 따라서 다음의 더 간결하고 쉬운 방법과는 별개로 알아둘 필요가 있습니다.
1. 펼침 연산자와 concat() 함수로 중첩 배열을 1차원 배열로 만들기
중첩 배열을 펼침 연산자로 펼친 후 빈 배열([])에 concat() 함수를 사용해서 하나로 합치는 간결하면서도 쉬운 방법입니다. 2 중첩 배열에만 사용할 수 있는 단점이 있지만, 속도가 빠르기 때문에 2 중첩 배열에 적용할 때 추천하는 방법입니다.
let array = [
["abc", "def"],
["ghi", "xyz"]
];
let newArray2 = [].concat(...array);
console.log(newArray2);// ['abc', 'def', 'ghi', 'xyz']
2. flat() 함수로 1차원 배열로 만들기
2중첩 이상의 배열을 1차원 배열로 변환해 주는 배열 내장 함수입니다.
"2 중첩 이상"이라고 한 것은 2 중첩, 3 중첩 등 다중첩 배열까지 1차원 배열로 변환해 주는 범용 함수이기 때문입니다.
별도의 인자를 넣지 않으면 2중첩 까지만 1차원 배열로 변환해 줍니다.
즉, 다중첩 배열에 별도의 인자 없이 flat() 함수를 사용하면 2중첩 까지만 1차원 배열로 변환하고, 더 깊은 중첩 배열은 중첩 상태가 그대로 유지됩니다.
다중첩 배열에 flat()을 사용할 때는 어느 중첩 단계까지 1차원 배열로 변환할지 깊이를 정수로 인자로 넘겨서 중첩을 풀 수 있습니다. flat(2)처럼 사용하면 2 중첩까지 1차원 배열로 변환해 줍니다.
앞서의 방법들처럼 중첩 깊이에 제한도 없고, 단일 함수로 간편하게 중첩 배열을 1차원 배열로 변환할 수 있어서 굳이 다른 변환 방법을 사용할 필요가 있을까 싶지만, 치명적인 단점이 있습니다.
flat() 함수는 속도가 느립니다.
펼침 연산자와 concat()를 사용하는 방법보다 평균적으로 1.5~2배 정도 느린 것으로 알려지고 있습니다.
웹 브라우저에 따라 다소 결과가 다르기는 하지만, 배열의 크기가 아주 크고 다중첩 배열이 아닌 경우 flat() 보다는 펼침 연산자와 concat()를 사용하는 방법을 더 추천합니다.
let data = [
["abc", "def"],
["ghi", "xyz"]
];
let newArray3 = data.flat();
console.log(newArray3);// ['abc', 'def', 'ghi', 'xyz']