Javascript - 만들면서 배우는 filter 함수의 정의와 사용 방법

이번 글에서는 자바스크립트의 filter() 함수를 직접 만들어보겠습니다. 가벼운 내용이지만 자바스크립트가 가진 filter() 함수를 구현해본다면 이전보다 filter() 함수에 대해 잘 이해할 수 있을 뿐만 아니라 함수형 프로그래밍이 가진 멋진 장점을 알 수 있습니다.

filter()를 사용하는 이유

 filter() 함수는 의미 그대로 "거르다"를 하기 위해 정의된 함수입니다. 예를 들어 특정 사용자 데이터(이름, 나이)가 주어지고 그중에서 특정 조건을 만족하는 대상들을 찾는 경우에 filter()를 사용할 수 있습니다. 선언적인 프로그래밍 방식으로 이 문제를 해결한다면 for문 혹은 while문을 사용해서 다음과 같은 방식으로 코드를 작성할 수 있습니다.

const users = [
  { name: 'a', age: 22 },
  { name: 'b', age: 21 },
  { name: 'c', age: 19 },
  { name: 'd', age: 30 },
  { name: 'e', age: 34 },
  { name: 'f', age: 31 },
  { name: 'g', age: 20 },
];

const result = [];

for (let i = 0; i < users.length; i++) {
  const user = users[i];
  if (user.age == 19) {
    result.push(user);
  }
}

console.log(result);

 filter()를 적용하면 위에서 정의한 코드를 어떻게 바꿀 수 있을까요?

const users = [
  { name: 'a', age: 22 },
  { name: 'b', age: 21 },
  { name: 'c', age: 19 },
  { name: 'd', age: 30 },
  { name: 'e', age: 34 },
  { name: 'f', age: 31 },
  { name: 'g', age: 20 },
];

const result = users.filter(user => user.age == 19);

console.log(result);

 

 filter() 함수를 적용하면 이와 같이 코드 라인 수를 줄일 수 있고 for문을 사용했을 때 보다 가독성이 좋은 코드를 만들 수 있습니다. 어떻게 보면 filter() 함수는 일급 함수를 잘 활용하는 예제라고 이야기할 수 있어요. 이제 filter()를 사용하는 이유에 대해서 알아보았으니 filter() 함수를 구현하는 방법을 알아보도록 하겠습니다.

filter() 함수를 만들어보자

 filter() 함수를 만드는 방법은 어렵지 않습니다. 다만 아직 구현해본 적이 없어서 해보지 않아서 막연히 어렵게 느껴질 뿐이죠. 그럼 본격적으로 filter() 함수를 만들어볼까요?

function _filter(array, predicate) {
  const arrayLength = array == null ? 0 : array.length;
  const result = [];

  for (let i = 0; i < arrayLength; i++) {
    const value = array[i];
    if (predicate(value)) {
      result.push(value);
    }
  }
  return result;
}

 filter() 함수는 필터링할 대상(array)과 필터링 방법(predicate)이 있으면 구현할 수 있습니다. 여기서 필터링 방법(predicate)은 일급 함수예요. 이 글에서는 일급 함수에 대한 개념을 다루지 않지만 filter() 함수를 구현하려면 이 개념은 꼭 알고 있어야 하는 부분이에요. 추가로 함수를 인자로 사용하는 함수는 고차 함수라고 이야기합니다. filter()는 고차 함수입니다.

 

 filter() 구현에서 주의 깊게 볼 부분은 필터링 방법(predicate)을 인자로 받아서 사용한다는 점입니다. 즉 filter를 사용하는 입장에서는 필터링 방법만 잘 정의해서 전달한다면 반복문(while문이나 for문)을 사용하지 않고 원하는 검색 결과를 얻을 수 있습니다. 조금 더 구체적으로 설명하자면 filter()는 배열의 반복문을 실행하고, 필터 조건 구분 방법은 값(일급 함수)으로 전달받아 대상이 되는 값을 판별해 값들을 반환하는 처리를 합니다.

 

 이 글에서 정의한 예제 코드에서는 filter() 함수의 옵션 부분까지 구현하지 않았습니다. MDN에서 정의한 filter 사양과 동일하게 구현하면 좋지만 옵션은 학습에 불필요하다고 생각했기 때문이에요. 직접 구현한 _filter() 함수를 사용하는 방법은 다음과 같습니다.

  const users = [
    { name: 'a', age: 22 },
    { name: 'b', age: 21 },
    { name: 'c', age: 19 },
    { name: 'd', age: 30 },
    { name: 'e', age: 34 },
    { name: 'f', age: 31 },
    { name: 'g', age: 20 },
  ];

  console.log(_filter(users, user => user.age > 10));
  console.log(_filter(users, user => user.age >= 20));
  console.log(_filter(users, user => user.age == 19));

 

Lodash의 filter() 함수

Lodash - filter()

 위의 캡처 내용은 Lodash에서 정의한 filter()의 구현 부분입니다. for문 대신 while문을 사용해 filter()를 구현 한 방법이 궁금하시다면 이 링크를 확인해보세요.

끝맺음

_filter(users, user => user.age == 19);
users.filter(user => user.age == 19);

 본문에서 사용한 filter() 함수들을 나란히 놓고 보면 차이가 있다는 것을 알 수 있습니다. 바로 함수를 조합해서 사용하는 경우와 객체가 가진 기능을 사용하는 경우가 있다는 것인데요. 끝으로 이렇게 다른 두 가지의 방식이 가지는 각각의 장단점을 고민해보면 어떨까요?

 

 이 글에서 사용한 코드는 Github 저장소를 통해서도 제공합니다. 그리고 filter()를 잘 활용하는 방법에 대해 알고 싶으시다면 이전에 정리한 filter() 함수의 활용 방법 글을 확인해주세요.

반응형

댓글

Designed by JB FACTORY