Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 중첩 배열을 병합해 1차원 배열로 만드는 방법

문제 상황

JavaScript에서 두 개의 중첩(nested) 배열 arr1arr2를 인자로 받아, 두 배열의 모든 요소를 하나의 1차원 배열로 평탄화(flatten)한 새로운 배열을 반환하는 함수를 작성해야 합니다.

예를 들어 함수에 다음과 같은 입력이 주어졌다고 가정해 보겠습니다.

const arr1 = [
    1, [
       2, [
          4, 5, [
             6
          ]
       ]
    ]
];
const arr2 = [
    11, 12, [
       16, 18, [
          19, 21, [
             23
          ]
       ]
    ]
];

이 경우 기대하는 출력 결과는 다음과 같습니다.

const output = [1, 2, 4, 5, 6, 11, 12, 16, 18, 19, 21, 23];

재귀를 활용한 해결 방법

중첩의 깊이가 정해져 있지 않기 때문에 재귀(recursion)를 사용하는 것이 가장 효과적입니다. 배열의 각 요소를 순회하면서 해당 요소가 배열이면 다시 자기 자신을 호출하고, 그렇지 않으면 결과 배열에 추가하는 방식입니다.

다음은 전체 코드입니다.

const arr1 = [
    1, [
       2, [
          4, 5, [
             6
          ]
       ]
    ]
];
const arr2 = [
    11, 12, [
       16, 18, [
          19, 21, [
             23
          ]
       ]
    ]
];
const flattenAndMerge = (arr1 = [], arr2 = []) => {
    const res = [];

    const flatten = (arr = []) => {
        for(let i = 0; i < arr.length; i++){
            if(Array.isArray(arr[i])){
                // 요소가 배열이면 재귀 호출로 더 깊이 탐색
                flatten(arr[i]);
            } else if(typeof arr[i] === 'number'){
                // 일반 값이면 결과 배열에 추가
                res.push(arr[i])
            };
        };
    };
    flatten(arr1);
    flatten(arr2);
    return res;
};
console.log(flattenAndMerge(arr1, arr2));

코드 동작 원리

위 코드의 핵심 로직은 다음과 같습니다.

  • 결과 저장소 생성: 최종적으로 모든 요소가 담길 빈 배열 res를 먼저 선언합니다.
  • 재귀 함수 정의: 내부 함수 flatten은 전달받은 배열을 순회하며 각 요소를 검사합니다.
  • 배열 판별: Array.isArray()로 요소가 배열인지 확인하고, 배열이라면 같은 함수를 재귀적으로 호출하여 내부까지 탐색합니다.
  • 값 추가: 배열이 아닌 숫자 값은 push()를 통해 결과 배열에 순서대로 저장됩니다.

실행 결과

콘솔 출력 결과는 다음과 같습니다.

[
    1, 2, 4, 5, 6,
    11, 12, 16, 18, 19,
    21, 23
]

참고: Array.prototype.flat() 활용하기

ES2019(ES10)부터는 flat() 메서드를 사용해 더 간단하게 구현할 수도 있습니다. 깊이를 무제한으로 지정하려면 Infinity를 인자로 넘기면 됩니다.

const flattenAndMerge = (arr1 = [], arr2 = []) =>
    [...arr1.flat(Infinity), ...arr2.flat(Infinity)];

이 방법은 코드가 훨씬 간결하지만, 문자열 등 특정 타입만 필터링하는 세부 제어가 필요하다면 앞서 소개한 재귀 방식이 더 유연합니다. 상황에 맞게 적절한 방법을 선택하시기 바랍니다.