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

JavaScript 객체 배열을 다른 배열 기준으로 필터링하는 방법

문제 상황

다음과 같은 객체 배열이 있다고 가정해 보겠습니다.

const arr = [
    {area: 'NY', name: 'Bla', ads: true},
    {area: 'DF', name: 'SFS', ads: false},
    {area: 'TT', name: 'SDSD', ads: true},
    {area: 'SD', name: 'Engine', ads: false},
    {area: 'NSK', name: 'Toyota', ads: false},
];

여기서 우리는 첫 번째 인수로 위와 같은 객체 배열을, 두 번째 인수로 문자열 리터럴 배열을 받는 JavaScript 함수를 작성해야 합니다.

이 함수는 각 객체의 area 속성 값이 두 번째 인수로 전달된 문자열 배열에 포함되어 있는 경우에만 해당 객체를 유지하도록 원본 배열을 필터링한 결과를 반환해야 합니다.

예제: for 루프를 사용한 구현

가장 기본적인 방식인 for 루프를 사용하여 작성한 코드는 다음과 같습니다.

const arr = [
    {area: 'NY', name: 'Bla', ads: true},
    {area: 'DF', name: 'SFS', ads: false},
    {area: 'TT', name: 'SDSD', ads: true},
    {area: 'SD', name: 'Engine', ads: false},
    {area: 'NSK', name: 'Toyota', ads: false},
];
const keys = ['NY', 'SD'];
const filterByArea = (arr = [], keys = []) => {
    const res = [];
    for(let i = 0; i < arr.length; i++){
        const { area } = arr[i];
        if(keys.includes(area)){
            res.push(arr[i]);
        };
    };
    return res;
};
console.log(filterByArea(arr, keys));

출력 결과

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

[
    { area: 'NY', name: 'Bla', ads: true },
    { area: 'SD', name: 'Engine', ads: false }
]

예상대로 area 값이 'NY' 또는 'SD'인 객체만 결과 배열에 포함된 것을 확인할 수 있습니다.

더 간결한 방법: filter() 메서드 활용

위 구현은 정확하지만 다소 장황합니다. ES6에서 도입된 Array.prototype.filter() 메서드와 includes()를 조합하면 동일한 로직을 한 줄로 표현할 수 있습니다.

const filterByArea = (arr = [], keys = []) =>
    arr.filter(({ area }) => keys.includes(area));

console.log(filterByArea(arr, keys));
// [{ area: 'NY', name: 'Bla', ads: true },
//  { area: 'SD', name: 'Engine', ads: false }]

구조 분해 할당({ area })을 통해 각 객체에서 필요한 속성만 꺼내고, 조건에 맞는 요소만 자동으로 걸러주므로 코드가 훨씬 읽기 쉬워집니다.

성능 팁: Set을 활용한 최적화

배열의 크기가 크거나 필터링 조건 목록이 길다면, includes()는 내부적으로 선형 탐색을 수행하기 때문에 O(n)의 시간이 걸립니다. 이 경우 Set으로 변환하면 조회가 O(1)로 개선됩니다.

const filterByArea = (arr = [], keys = []) => {
    const keySet = new Set(keys);
    return arr.filter(({ area }) => keySet.has(area));
};

마무리

객체 배열을 다른 배열의 값을 기준으로 필터링할 때는 filter()includes()(또는 대량 데이터 처리 시 Set.has())를 조합하는 것이 가장 깔끔하고 효율적인 접근 방식입니다. 상황에 맞게 선택하여 사용하시기 바랍니다.