사고의 추상화(feat. filter, map, reduce)
추상화?
복잡한 어떤 것을 압축해서 핵심만 추출한 상태로 만드는 것이 추상화
우리 일상에서 추상화가 아닌것을 찾아보기 힘들다.
네이버 검색창에 검색어를 입력 했을 때, 검색어가 어떻게 입력이 되고 데이터가 전송이되고 어떻게 처리되는지... 알지 않아도 우리는 편하게 검색어만 입력해서 사용할 수 있다.
카카오톡에서 메세지를 보낼 때, 메세지를 입력하지만 이 메세지가 어떻게 입력이되고 어떻게 서버에 전송이되는지 알지 않아도 우리는 편하게 메세지를 보낸다.
이렇듯 추상화는 우리 일상의 대부분을 차지한다.
자바스크립트를 비롯한 대부분의 언어 역시, 추상화의 결과이다. 크롬 개발자 도구 console에서 코드를 입력하면 보이지 않는? 우리가 과정을 알지 못해도 코드의 결과를 볼 수 있다. 이 과정을 자바스크립트 해석기(엔진)이 해준다.
이렇듯 프로그램을 작성할 때, 자주 반복해서 사용하는 로직은 별도의 함수로 작성하기도 한다. 이 역시 추상화의 좋은 사례이다.
추상화의 관점에서 함수를 바라보면, 함수는 사고(thought) 또는 논리(logic)의 묶음이다.
const data = [
{
gender: 'male',
age: 24,
},
{
gender: 'male',
age: 25,
},
{
gender: 'female',
age: 27,
},
{
gender: 'female',
age: 22,
},
{
gender: 'male',
age: 29,
},
];
위와 같이 주어진 데이터를 순차적으로 처리하려고 할 때, 모든 작업을 하나의 함수로 작성할 수 있다. 예를 들어 남성들의 평균 나이를 구한다고 할 때에는, 다음과 같이 함수를 작성할 수 있다.
먼저 "남성들의 평균 나이를 구하기 위한" 과정을 생각해보자
1. data 배열의 요소인 각 객체안에 남성을 가진 요소만 filtering하기
2. filtering한 배열의 요소 길이를 변수로 지정하기(평균을 내기 위해서)
3. 1번의 filtering한 배열의 요소(객체)에 age만 골라내기 위해 mapping하기
4. mapping한 배열의 요소들을 reducer를 사용하여 응축(합침)하기
5. 응축한 값을 2번의 변수로 나눠주기
이 과정을 코드로 작성해보자
function getAverageAgeOfMaleAtOnce(data) {
const onlyMales = data.filter(function (d) {
// data.filter는 배열의 각 요소에 인자로 전달받은 함수를 적용하고,
// 그 결과가 true인 요소만을 갖는 배열을 리턴합니다.
return d.gender === 'male';
});
const numOfMales = onlyMales.length;
const onlyMaleAges = onlyMales.map(function (d) {
// onlyMales.map는 배열의 각 요소에 인자로 전달받은 함수를 적용하고,
// 각 결과를 요소로 갖는 배열을 리턴합니다.
return d.age;
});
const sumOfAges = onlyMaleAges.reduce(function (acc, cur) {
// onlyMaleAges.reduce는 배열의 각 요소에 인자로 전달받은 함수를 적용하고,
// 각 결과를 두 번째 인자로 전달받은 초기값(0)에 누적한 결과를 리턴합니다.
return acc + cur;
}, 0);
return sumOfAges / numOfMales;
}
위 코드는 남성의 나이를 평균 내기위한 추상화 코드 이지만
남성 중 최연소 나이를 구하는 등 다양한 조건에 사용하지는 못한다.
조금 더 일반적으로 사용할수 있는 로직을 찾아보도록 하자...나중에..