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

JavaScript에서 한 배열을 기준으로 다른 배열 필터링하는 방법


문제 상황

다음과 같이 사람 정보를 담은 객체 배열과, 필터링 기준이 될 이름 문자열 배열이 있다고 가정해 보겠습니다.

const main = [
    {name: "Karan", age: 34},
    {name: "Aayush", age: 24},
    {name: "Ameesh", age: 23},
    {name: "Joy", age: 33},
    {name: "Siddarth", age: 43},
    {name: "Nakul", age: 31},
    {name: "Anmol", age: 21},
];
const names = ["Karan", "Joy", "Siddarth", "Ameesh"];

여기서 작성해야 할 함수는 두 개의 배열을 인자로 받아, 첫 번째 배열(main)에서 name 속성이 두 번째 배열(names)에 포함된 객체만 남기고 나머지는 모두 제거하는 역할을 합니다. 특히 이 예제는 새로운 배열을 반환하는 대신 원본 배열 자체를 직접 수정(in-place)한다는 점이 핵심입니다.

예제 코드

const main = [
{name: "Karan", age: 34},
{name: "Aayush", age: 24},
{name: "Ameesh", age: 23},
{name: "Joy", age: 33},
{name: "Siddarth", age: 43},
{name: "Nakul", age: 31},
{name: "Anmol", age: 21},
];
const names = ["Karan", "Joy", "Siddarth", "Ameesh"];
const filterUnwanted = (main, names) => {
    for(let i = 0; i < main.length; ){
       if(names.includes(main[i].name)){
          i++;
          continue;
       };
       main.splice(i, 1);
    };
};
filterUnwanted(main, names);
console.log(main);

코드 동작 원리

핵심 로직을 단계별로 살펴보면 다음과 같습니다.

  • names.includes(main[i].name) : 현재 객체의 name 값이 두 번째 배열에 존재하는지 확인합니다.
  • 포함된 경우 : 인덱스 i를 1 증가시킨 뒤 continue로 다음 요소로 넘어갑니다.
  • 포함되지 않은 경우 : splice(i, 1)로 해당 요소를 제거합니다. 이때 인덱스를 증가시키지 않는 이유는, 요소가 제거되면 뒤에 있던 요소들이 앞으로 당겨지기 때문입니다. 인덱스를 그대로 두어야 당겨진 요소를 검사하지 않고 건너뛰지 않을 수 있습니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.

[
    { name: 'Karan', age: 34 },
    { name: 'Ameesh', age: 23 },
    { name: 'Joy', age: 33 },
    { name: 'Siddarth', age: 43 }
]

names 배열에 포함된 네 개의 객체만 남고, 나머지 세 개의 객체는 원본 배열에서 성공적으로 제거된 것을 확인할 수 있습니다.

참고: filter()를 활용한 더 간단한 방법

원본 배열을 유지하면서 새로운 배열을 만들어도 괜찮다면, ES6의 filter() 메서드를 사용하는 것이 훨씬 간결하고 가독성이 좋습니다.

const filtered = main.filter(item => names.includes(item.name));
console.log(filtered);

다만 이 방식은 원본 배열을 변경하지 않고 새 배열을 반환한다는 차이가 있습니다. 따라서 원본 데이터를 반드시 보존해야 하는지, 메모리 사용량이나 성능이 중요한 상황인지에 따라 적절한 방식을 선택하시면 됩니다.