filter

이효범·2022년 4월 4일
0

ES6 - OOP & FRP

목록 보기
3/15
post-thumbnail

Array는 Array Class의 인스턴스이다. 따라서 Array Class에 정의되어 있는 메소드들을 활용할 수 있다. 주인장은 Array의 헬퍼 메소드들을 통해 OOP와 FRP의 기초에 대해 공부해보려 한다.

filter

let heroes = [{ name: 'superman', type: 'Flying', cost: 400 }, 
              { name: 'batman', type: 'Flying', cost: 320 }, 
              { name: 'X-man', type: 'Mutant', cost: 200 }, 
              { name: 'Ironman', type: 'Metal', cost: 530 },  
              { name: 'Antman', type: 'Insect', cost: 180 }];

// Filtering Heroes
let filterHeroes = [];  


// Impelative
for(let i = 0; i < heroes.length; i++) {
  if(heroes[i].type === 'Flying' && heroes[i].cost > 300) {
   	filterHeroes.push(heroes[i]); 
  }
}
// Declarative
filterHeroes = heroes.filter(function(hero) {
	return hero.type === 'Flying' && hero.cost > 300;
});

위의 예시처럼 filter 또한 forEach 와 map 과 비슷한 느낌이다만 기능이 약간 틀리다.
그래도 예시를 보면 알 수 있듯 filter 메소드는 아주 유용하며 간결한 코드 작성을 할 수 있도록 도와준다.

위 예시는 3개의 키값만 있는 간단한 예제이지만, 앞으로 보게 될 웹 예제 혹은 어플리케이션 프로젝트에서는 키값이 100개가 넘는 것을 필터링해야할 수도 있다. 이럴 때 우리가 원하는 형태, 가공된 데이터를 간단하게 뽑아내주는 기능을 filter를 이용해 뽑아낼 수 있다.

filter 연습

첫번째 연습문제

// 1. Filter numbers larger than 50.
let numbers = [15, 25, 35, 45, 55, 65, 75, 85, 95];

let filteredNumbers;

// 2. filter users having admin right.
let users = [
    { id: 1, admin: true },
    { id: 2, admin: false },
    { id: 3, admin: false },
    { id: 4, admin: false },
    { id: 5, admin: true },
];

let filteredUsers;
// 1. Filter numbers larger than 50.
filteredNumbers = numbers.filter(el => el > 50);

// 2. filter users having admin right.
filteredUsers = users.filter(el => el.admin === true);

두번째 연습문제
위의 예시와 연습문제까지는 하나의 변수로만 필터링을 적용했었다. filter를 이용해 좀 더 다양한 기능을 구현할 수 있다.

let heroes = [
    { id: 1, name: 'superman', type: 'Flying', cost: 400 },
    { id: 2, name: 'batman', type: 'Flying', cost: 320 },
    { id: 3, name: 'X-man', type: 'Mutant', cost: 200 },
    { id: 4, name: 'Ironman', type: 'Metal', cost: 530 },
    { id: 5, name: 'Antman', type: 'Insect', cost: 180 },
];

let comments = [
    { idOfWriter: 1, content: '아름다운 우리 나라' },
    { idOfWriter: 2, content: '아름다운 박쥐 나라' },
    { idOfWriter: 1, content: '아름다운 크립톤' },
    { idOfWriter: 3, content: '아름다운 장미 한송이' },
    { idOfWriter: 5, content: '아름다운 제주도 밤바다' },
    { idOfWriter: 4, content: '아름다운 제주도 한라산' },
    { idOfWriter: 4, content: '아름다운 올레길' },
    { idOfWriter: 2, content: '아름다운 돌담길' },
];

// 슈퍼맨이 적은 댓글만 뽑아내시오.
let supermanComment;

위의 예시를 보면 heroes 와 comments가 있다. 이러한 두개의 데이터는 각각 따로 데이터베이스의 스토어에 저장이 되게 된다. 이러한 상황에서 슈퍼맨이 적은 댓글만 뽑아 내고 싶을 때에는 어떻게 해야할까?
(위 예시에서는 heroes와 idOfWriter의 아이디는 동일하다고 가정한다.)

function commentPerWriter(comments, id) {
    let sorted = comments.filter(comment => comment.idOfWriter === id);
    return sorted;
}

console.log(commentPerWriter(comments, 1));

좀 더 복잡한 조건의 필터링도 연습해보자. 위에같은 경우는 슈퍼맨의 아이디를 넣었을 때 그 조건에 따라 comments에서 필터링을 하는 경우다.
그렇다면 아이디 값이 아니라 'superman'을 넣는다면 어떻게 해야 할것인가?
heroes 배열에서 'superman'을 찾고, 그의 아이디값을 찾는다.
그리고 나서 comments에 아이디값을 전달하고 필터링을 하는 식의 두 단계를 거치는 로직을 이용해 원하는 필터링을 구현할 수 있다.

function commentPerWriter(comments, name) {
    function searchId(heroes, name) {
        return heroes.filter(function (hero) {
            return hero.name === name;
        });
    }
    let searchedHero = searchId(heroes, name);

    let sorted = comments.filter(comment => comment.idOfWriter === searchedHero[0].id);
    return sorted;
}

console.log(commentPerWriter(comments, 'superman'));

위의 논리구조도 물론 타당하지만, 좀 더 간결하게 구현할 수도 있다. 이에 대해서는 RxJS에 대한 글을 쓰게 될 시기에 다시 한번 다루도록 하겠다.

세번째 연습문제

// Example
let numbers = [10, 20, 30];
let lessThanFifteen = reject(numbers, function (number) {
    return number >= 15;
});
console.log(lessThanFifteen); // [10];

// Implement reject();
function reject(array, iteratorFunction) {}

위의 예제는 reject라는 반대되는 결과값을 리턴하는 함수를 구현하는 문제이다.
lessThanFifteen이라는 변수는 15보다 작은 숫자를 리턴해야 하지만, reject함수를 인자로 넘겨줬을시에는 그의 반대의 조건을 적용해서 리턴을 해야 한다.

// Implement reject();
function reject(array, iteratorFunction) {
    return array.filter(item => !iteratorFunction(item));
}

혹은 forEach를 사용해서도 구현할 수 있다.

function reject(array, iteratorFunction) {
    let results = [];
    array.forEach(function (el) {
        if (!iteratorFunction(el)) results.push(el);
    });
    return results;
}
profile
I'm on Wave, I'm on the Vibe.

0개의 댓글