알고리즘/JavaScript

JavaScript) 배열 메소드 filter와 find 사용하기.

홍구리당당 2023. 10. 30. 21:01

0. 오늘의 배울 것

js의 배열 메소드 중에는 filter과 find가 있다. 이름에서 알 수 있듯이, 배열의 요소들을 하나씩 살펴보면서 요소를 찾는 동작을 하는 메소드이다.

가끔 프로그래머스나 백준에서 배열 내 어떠한 조건에 맞는 값들을 찾으라는 문제가 주어지는데, 그 때 사용하면 좋을 메소드들이다!

1. 배열 메소드 filter

filter 메소드는 map 메소드와 비슷하게 새로운 배열을 만들어 리턴해준다.

때문에 인자로 넣어줄 콜백함수에 리턴문을 써줘야 한다.

주의할 점은 콜백함수의 리턴문에는 어떠한 값이 아니라 true false를 도출하는 조건문을 적어야 한다는 것이다.

const foods = [
  {name: "apple", brand: "fruit"},
  {name: "banana", brand: "fruit"},
  {name: "pork", brand: "steak"},
  {name: "cherry", brand: "fruit"},
  {name: "melon", brand: "fruit"},
  {name: "beef", brand: "steak"},
  {name: "mutton", brand: "steak"},
  {name: "orange", brand: "fruit"},
]

const fruits = foods.filter((obj) => {
    return (obj.brand === "fruit");
});

filter 메소드는 항상 배열을 리턴해주기 때문에, 조건에 맞는 원소를 한 개만 찾았다 하더라도 그 원소 자체를 리턴해주는 게 아니라 그 원소가 담긴 길이 1짜리 배열을 리턴해준다.

// 배열 길이가 1짜리인 배열을 넘겨줌.

const nums = [1, 2, 3, 4];

const one = nums.filter((el) => {
    return (el === 1);
});

console.log(one); // [1] 출력함.

때문에 리턴받은 새로운 배열을 펼쳐서 사용하려면 spread 구문과 섞어서 사용하면 된다.

filter 메소드의 콜백함수에도 인자를 3개까지 넣을 수 있다.

// 유일한 값 하나를 배열이 아닌 원소 그대로 넘겨줌.
const foods = [
  {name: "apple", brand: "fruit"},
  {name: "banana", brand: "fruit"},
  {name: "pork", brand: "steak"},
  {name: "cherry", brand: "fruit"},
  {name: "melon", brand: "fruit"},
  {name: "beef", brand: "steak"},
  {name: "mutton", brand: "steak"},
  {name: "orange", brand: "fruit"},
]

const myDinner = foods.filter((obj, i, arr) => {
  console.log(i);
  console.log(obj);
  console.log(arr);    return (obj.brand === "fruit");
});
// 배열을 전체 순회하기 때문에 console.log 문은 배열 길이만큼 반복된다.

2. 배열 메소드 find

앞서 배운 filter 메소드는 배열의 모든 요소들을 한 번씩 참조하면서 조건에 맞는 값들을 찾아 새로운 배열을 리턴해주는 메소드였다.

반면 find 메소드는, 조건에 맞는 값을 찾으면 그 순간 반복문을 종료한다!!

즉, filter 메소드는 배열 내 조건에 맞는 여러 원소들을 찾을 때, find 메소드는 배열 내 조건에 맞는 원소를 하나만 찾을 때 주로 사용된다.

// 유일한 값 하나를 배열이 아닌 원소 그대로 넘겨줌.
const foods = [
  {name: "apple", brand: "fruit"},
  {name: "banana", brand: "fruit"},
  {name: "pork", brand: "steak"},
  {name: "cherry", brand: "fruit"},
  {name: "melon", brand: "fruit"},
  {name: "beef", brand: "steak"},
  {name: "mutton", brand: "steak"},
  {name: "orange", brand: "fruit"},
]

const myDinner = foods.find((obj) => {
    return (obj.name === "apple");
});

console.log(myDinner); // {name: "apple", brand: "fruit"} 출력함

또한 find 메소드의 콜백 함수에도 인자를 3개까지 넣을 수 있다.

const foods = [
  { name: "apple", brand: "fruit" },
  { name: "banana", brand: "fruit" },
  { name: "pork", brand: "steak" },
  { name: "cherry", brand: "fruit" },
  { name: "melon", brand: "fruit" },
  { name: "beef", brand: "steak" },
  { name: "mutton", brand: "steak" },
  { name: "orange", brand: "fruit" },
];

const myDinner = foods.find((obj, i, arr) => {
  console.log(i);
  console.log(obj);
  console.log(arr);
  return obj.name === "banana";
});
// 배열을 전체 순회하다가 원소를 찾으면 멈추기 때문에 console.log 문은 2번 반복되고 끝난다.

참고로 find 메소드는 없는 값을 찾으려 하면 undefined를 리턴한다.

3. 정리

  1. filter 메소드는 배열을 전체 순회한 후 새로운 배열을 리턴한다.
  2. find 메소드는 배열을 순회하다가 값을 찾으면 바로 종료하고 해당 값을 리턴한다.
  3. filter과 find 메소드 둘 다 콜백 함수에 return 문을 적어야 한다.
  4. filter, find 메소드 둘 다 최악 시간복잡도는 O(n)이지만 평균 시간복잡도는 find 메소드가 더 짧다.
  5. 조건에 만족하는 값이 없을 경우 filter 메소드는 빈 배열 [], find 메소드는 undefined 값을 리턴.
  6. forEach, map 메소드와 마찬가지로 filter, find 메소드도 콜백함수의 파라미터로 (배열요소, 요소의 인덱스, 배열 자체) 총 3개까지 받을 수 있다.