본문 바로가기
개발 공부/웹개발

자바스크립트_기본 함수 구현하기(_.filter, _.uniq, _.each,_.map, _.reduce)

by 크롱이크 2021. 5. 19.

이번 주에는 자바스크립트 유틸리티 라이브러리 underscore의 함수들을 직접 구현하는 과제를 받았습니다. 

 

그중에서 제가 중요하다고 생각하는 몇가지만 정리해보겠습니다.

_.each

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *  배열 arr을 입력받을 경우, iteratee(ele, idx, arr)
 *  객체 obj를 입력받을 경우, iteratee(val, key, obj)
 * 이처럼 collection의 모든 정보가 iteratee의 인자로 잘 전달되어야 모든 경우를 다룰 수 있습니다.
 * 실제로 전달되는 callback 함수는 collection의 모든 정보가 필요하지 않을 수도 있습니다.
 */
 
// _.each는 명시적으로 어떤 값을 리턴하지 않습니다. Array.prototype.forEach
_.each = function (collection, iteratee) {
  // TODO: 여기에 코드를 작성합니다.
  //? 배열일 경우
  if(Array.isArray(collection)){
    for(let i=0; i < collection.length ; i++ ){
      iteratee(collection[i] , i , collection);
    }
  }
//? 객체일 경우
  else if(typeof collection === 'object' && collection !==null){
    for(let key in collection){
      iteratee(collection[key] , key , collection )
    }
  }
};
forEach는 라는 함수를 구현해보았다. 배열일때와 객체일때 전달되어져야 하는 인자가 다르다. 
배열인 경우에는 (요소,  인덱스, 배열)이 주어지고,
객체는 (키값, 키, 객체) 가 주어져야한다.

_.indexOf

1
2
3
4
5
6
7
8
9
10
11
12
_.indexOf = function (arr, target) {
 
  let result = -1;
 
  _.each(arr, function (item, index) {
    if (item === target && result === -1) {
      result = index;
    }
  });
 
  return result;
};
cs
indexOf는 배열안에 찾는 요소가 있을시 인덱스 넘버를 리턴해주는 함수이다.
아무것도 없을때는 -1을 반환한다.
target과 위에서 만든 _.each함수에서 item이 같다면, 인덱스 넘버를 리턴한다.

_.filter

1
2
3
4
5
6
7
8
9
10
11
12
13
// _.filter는 test 함수를 통과하는 모든 요소를 담은 새로운 배열을 리턴합니다.
 
_.filter = function (arr, test) {
  
  let result = [];
  _.each(arr, function(el){
    if(test(el)){
      result.push(el);
    }
  })
  return result;
};
 
cs
_.filter 함수는 배열안의 요소를 순회하며 조건에 맞는 요소를 골라 새로운 배열에 추가하여 리턴하는 함수이다.
_.each를 활용하여 요소마다 접근하여 진행하게된다.

_.uniq

1
2
3
4
5
6
7
8
9
10
11
12
// _.uniq는 주어진 배열의 요소가 중복되지 않도록 새로운 배열을 리턴합니다.
 
_.uniq = function (arr) {
  let result = [];
 
  _.each(arr, function(el){
    if(_.indexOf(result, el) === -1){
      result.push(el);
    }
  });
  return result;
};
cs
배열안에 중복되는 요소를 제거하여 새로운 배열로 리턴하는 함수이다.
여기서는 위에서 만든 indexOf를 사용하였다. 존재하지 않다면 -1이 나오기에 -1이 나온다면 새로운 배열에 요소를 push한다.

_.map

1
2
3
4
5
6
7
8
9
10
11
// _.map은 iteratee(반복되는 작업)를 배열의 각 요소에 적용(apply)한 결과를 담은 새로운 배열을 리턴한다.
// 함수의 이름에서 드러나듯이 _.map은 배열의 각 요소를 다른 것(iteratee의 결과)으로 매핑(mapping)한다.
 
_.map = function (arr, iteratee) {
 
  let result=[];
  _.each(arr, function(el){
    result.push(iteratee(el));
  });
  return result;
};
cs
map이라는 함수는 함수를 적용시켜 새로운 배열로 만든다.
filter와는 다르게 조건이 들어가서 일치하는 것만 꺼내는 것이 아니라, 전체에 함수를 적용시켜 새로운 배열에 push 해야한다.

_.reduce

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//_.reduce는
//  1. 배열을 순회하며 각 요소에 iteratee 함수를 적용하고,
//  2. 그 결과값을 계속해서 누적(accumulate)합니다.
//  3. 최종적으로 누적된 결과값을 리턴합니다.
 
_.reduce = function (arr, iteratee, initVal) {
  let acc = initVal;
 
  _.each(arr, function (item, idx, src) {
    if (initVal === undefined && idx === 0) {
     acc = item;
    } else {
     acc = iteratee(acc, item, idx, src);
    }
  });
 
  return accumulator;
};
cs
가장 까다로웠다. reduce도 3개의 인자를 받아온다. (배열, 함수, 초기값) 
acc라는 변수에 초기값(initVal)이 있다면 넣어줘야한다. 
만약 undefined거나 0이라면, 배열의 첫 요소가 acc가 된다.
 each는 배열안의 요소 하나씩 접근하는 요소이므로 다시 돌며 else로 들어가 계속해서 함수를 적용하여, acc에 재할당해준다.
누적된 결과값을 알 수있다. 

 

자바스크립트에서 활용하는 함수를 구현해 보았습니다.

함수들을 구현해봄으써 그 함수가 어떻게 활용되고 있는지 자세히 알게 되었습니다. 이 과제를 통해 코드스테이츠에서 왜 이런 과제를 냈는지 이해가 되는 시간이였습니다.  

반응형

댓글