Underbar

이동국·2022년 9월 25일

Underbar


이번 시간에는 페어분과 함께 자바스크립트의 내장 메서드에 대해 배웠다.
우리는 이전에 forEach, map, filter, reduce 등과 같은 내장 메서드를 사용한 적이 있는데, 페어분과 함께 과제로 underbar라는 라이브러리를 직접 구현하면서 자바스크립트 내장 메서드가 어떻게 콜백함수를 활용하는지 원리에 대해 알게 되었다.

slice

_.slice = function (arr, start, end) {
   let _start = start || 0,
       _end = end;
    if (start < 0) _start = Math.max(0, arr.length + start);
  if (end < 0) _end = Math.max(0, arr.length + end);
  if (_end === undefined || _end > arr.length) _end = arr.length;
   let result = [];
  for (let i = _start; i < _end; i++) {
    result.push(arr[i]);
  }

  return result;
};

take

_.take = function (arr, n) {
  // n이 undefined이거나 음수인 경우, 빈 배열을 리턴합니다.
  if (n <= 0 || n === undefined) {
    return [];
  }

  // n이 배열의 길이를 벗어날 경우, 전체 배열을 shallow copy(같은 참조값을 가지는)한 새로운 배열을 리턴합니다. 얕은복사
  // 이렇게 반복되는 if문을 OOP형태로 재사용 가능한 형태로 만들 수 있음? 
  if (n > arr.length) {
    let _arr;
    _arr = arr;

    return _arr;
  }

  let result = [];
  // _.take는 배열의 처음 n개의 element를 담은 새로운 배열을 리턴합니다.
  for (let i = 0; i < n; i++) {
    result.push(arr[i]);
  }
  return result;

};

drop

_.drop = function (arr, n) {
  // n이 undefined이거나 음수인 경우, 전체 배열을 shallow copy한 새로운 배열을 리턴합니다.
  if (n <= 0 || n === undefined) {
    let _arr;
    _arr = arr;

    return _arr;
  }

  // n이 배열의 길이를 벗어날 경우, 빈 배열을 리턴합니다.
  if (n > arr.length) {
    return [];
  }


  let result = [];

  for (let i = n; i < arr.length; i++) {
    result.push(arr[i]);
  }
  return result;
};

last

_.last = function (arr, n) {
  let result = [];

  if (n === 0) {
    return result;
  }

  // n이 undefined이거나 음수인 경우, 배열의 마지막 요소만을 담은 배열을 리턴합니다.
  if (n < 0 || n === undefined) {
    result.push(arr[arr.length-1]);
    return result;
  }
  // n이 배열의 길이를 벗어날 경우, 전체 배열을 shallow copy한 새로운 배열을 리턴합니다.
  if (n > arr.length) {
    let _arr;
    _arr = arr;

    return _arr;
  }
  // _.last는 배열의 마지막 n개의 element를 담은 새로운 배열을 리턴합니다.
  result = _.slice(arr ,arr.length-n, arr.length)
  return result;
};

each

_.each = function (collection, iteratee) {
  // for of로 할때 이상하게 됨
  // 배열인지 객체인지 먼저확인
  if (Array.isArray(collection)){
    for(let i = 0; i < collection.length; i++){
      iteratee(collection[i], i, collection)
    }
  } else {
    for(let i in collection) {
      iteratee(collection[i], i , collection)
    }
  }
};

indexOf

_.indexOf = function (arr, target) {
  let result = -1;

  _.each(arr, function (item, index) {
    if (item === target && result === -1) {
      result = index;
    }
  });

  return result;
};

filter

_.filter = function (arr, test) {
  let newArr = [];
  // boolean으로 element 나누기 <- callback 1번째 

  // 배열의 모든 요소를 함수에 적용시키기 
  _.each(arr, function(item) {
   if (test(item)) {
     newArr.push(item)
   }
 });
 return newArr;
};

reject

_.reject = function (arr, test) {
   // 새로운 배열을 하나 선언 
   let newArr = [];
   // boolean으로 element 나누기 <- callback 1번째 
 
   // 배열의 모든 요소를 함수에 적용시키기 
   _.each(arr, function(item) {
    if (!test(item)) {
      newArr.push(item)
    }
  });
  return newArr;
};

uniq

_.uniq = function (arr) {
  let newArr = [];

  _.each(arr, function (item, index) {
    if(_.indexOf(arr, item) === index) {
      newArr.push(item);
    }
     
  });
  return newArr;
};

map

_.map = function (arr, iteratee) {
  let result = [];
  _.each(arr, function (item){
    result.push(iteratee(item));
  })
  return result;
};

pluck

_.pluck = function (arr, keyOrIdx) {
  return _.map(arr, function(el){
    return el[keyOrIdx];
  })
};

reduce

_.reduce = function (arr, iteratee, initVal) {
  let acc = initVal;
  _.each(arr, function(ele, idx) {
    if (acc === undefined) {
      acc = ele;
    } else {
      acc = iteratee(acc, ele, idx, arr);
    }
  }) 
  return acc;
};

0개의 댓글