filter()?
filter는 자바스크립트 Array 객체의 내장 매서드로, 기본적으로는 배열의 각 원소들을 순회하며 콜백함수를 실행하고, 리턴값이 true인 경우의 원소만을 모아서 새로운 배열을 리턴해주는 매서드이다.
단순히 배열에서 특정 조건외의 원소들을 배제 시킬때도 사용하며, 개인적으로는 중복을 허용하는 숫자로 이루어진 원소들중 해당 원소가 몇번째인지를 구할때라던가, 혹은 배열에서 중복값을 제거하는등의 응용해서 사용하는 방식이 흥미로웠다.
사용법
Array.filter((element, index, originArr) => {
//some function...
})
// - - - - - -
const numberArr = [1,2,3,4,5,6,7];
// 3 이하의 원소들로 이루어진 배열을 구하려면..
const underThreeArr = numberArr.filter(el => el <= 3);
console.log(underThreeArr)
//[1, 2, 3]
map() 이랑 유사하지만 callback 함수의 return 값이 true, false 여야한다.
주로 이름처럼 필터기능을 구현할때 사용하곤 한다.
const userData = [
{name: "a", age: 18},
{name: "b", age: 12},
{name: "c", age: 21},
{name: "d", age: 17},
{name: "e", age: 19},
{name: "f", age: 30},
{name: "g", age: 24}
]
const adultUsers = userData.filter(el => el.age > 19);
console.log(adultUsers)
/*
[
{ "name": "c", "age": 21 },
{ "name": "f", "age": 30 },
{ "name": "g", "age": 24 }
]
*/
응용사례1 - 중복된 값이 있는 배열의 순위 구하기
예를들어 시험 성적 데이터가 있다고 가정해보고, 등수를 매긴다고 할때,
중복되는 점수가 없다면 상관없지만, 100점, 95점, 95점, 80점, 75점 이런식으로 점수가 분포한다면
80점인 학생은 3등이 아닌 4등이 되어야 한다.
이런 부분을 계산할때 filter 매서드는 유용하게 사용 될 수 있다.
const student = [
{name: "a", score: 100},
{name: "b", score: 95},
{name: "c", score: 95},
{name: "d", score: 80},
{name: "e", score: 75},
{name: "f", score: 75},
{name: "f", score: 60}
]
student.map((el, idx, arr) => {
return {
...el,
rank: arr.filter(({score}) => score > el.score).length + 1
}
})
/*
[
{ "name": "a", "score": 100, "rank": 1 },
{ "name": "b", "score": 95, "rank": 2 },
{ "name": "c", "score": 95, "rank": 2 },
{ "name": "d", "score": 80, "rank": 4 },
{ "name": "e", "score": 75, "rank": 5 },
{ "name": "f", "score": 75, "rank": 5 },
{ "name": "f", "score": 60, "rank": 7 }
]
*/
map()과 filter()를 같이 사용해서 각 학생들의 등수를 구했다.
배열을 돌면서 주어진 socre(자신의 점수)보다 낮은 score들의 갯수를 리턴해주면 된다.
응용사례2 - 배열 내의 중복된 값 제거하기
배열 내에서 중복된 값을 제거하는 방법에는 다양한 방법이 있지만 fitler() 매서드를 이용해서도 중복되는 값을 제거할 수 있다.
const dupliArr = [1,1,1,2,3,3,4,4,4,4,5,5,5,5];
const removeDupliArr = dupliArr.filter((el, idx, arr) => arr.indexOf(el) === idx);
console.log(removeDupliArr)
// [1, 2, 3, 4, 5]
map()과 마찬가지로 3번째 매개변수로 호출한 배열을 사용할 수 있는걸 응용해서
호출한 배열에서 현재 원소의 순서를 가져온뒤, 2번째 매개변수인 현재 원소의 순서와 같다면
(최초로 나온 원소라면) 추가해주고, 그게 아니라면 추가하지 않는 방식이다.
indexOf()가 배열 내에서 가장 첫번째 매서드를 반환하는 성질을 응용한 방식이다.
응용사례3 - 배열 내 특정 idx의 원소 제거하기
slice()에서도 다루었지만 배열내의 특정 idx의 원소를 제거할 수 있다.
const arr = [1,2,3,4,5,6,7,8,9];
//3을 제거 하고 싶다면..
const targetIdx = arr.indexOf(3);
arr.filter((el, idx) => idx !== targetIdx)
//[1, 2, 4, 5, 6, 7, 8, 9]