TIL 28일차

안광의·2021년 7월 26일
0

Today I Learned

목록 보기
28/64
post-thumbnail
post-custom-banner

시작하며

오늘은 비동기 챕터를 본격적으로 들어가기 전에 고차함수와 Callback 함수에 대해서 복습하고 배열 메소드가 브라우저에서 지원되지 않을때 사용하던 underscroe.js 라이브러리를 실제로 구현하는 스프린트를 진행하였다.

underscore.js

_.identity = function (val) {
  return val;
};

_.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 = function (arr, n) {
  let result = [];
  if (n < 0 || n === undefined) {
    return result;
  }

  if (n >= arr.length) {
    return arr;
  }

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

_.drop = function (arr, n) {
  let result = [];
  
  if (n < 0 || n === undefined) {
    return arr;
  }

  if (n > arr.length) {
    return result;
  }

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

  return result;
};

_.each = function (collection, iteratee) {
  if (Array.isArray(collection)) {
    for (let i = 0; i < collection.length; i++) {
      iteratee(collection[i], i, collection)
    }
  }
  else {
    for (let key in collection) {
      iteratee(collection[key], key, collection)
    }
  }
};

_.indexOf = function (arr, target) {

  let result = -1;

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

  return result;
};

_.filter = function (arr, test) {
  let result = [];
  _.each(arr, (el) => {
    if (test(el)) {
      result.push(el)
    }
  })

  return result;
};


_.reject = function (arr, test) {
  let result = [];
  _.each(arr, (el) => {
    if (!test(el)) {
      result.push(el)
    }
  })

  return result;
};

_.uniq = function (arr) {
  let result = [];
  _.each(arr, (el) => {
    if (_.indexOf(result, el) === -1) {
      result.push(el);
    }
  })
  return result;
};

_.map = function (arr, iteratee) {

  let result = [];
  _.each(arr, (el) => {
    result.push(iteratee(el));
  })
  return result;
};


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

};

_.reduce = function (arr, iteratee, initVal) {
  if (initVal === undefined) {
    initVal = arr[0];
    arr = _.slice(arr, 1)
  }

  _.each(arr, (el, i, reduceArr) => {
    initVal = iteratee(initVal, el, i, reduceArr)
  })

  return initVal;

};

_.once = function (func) {
  let isCalled = false;
  let result
  return function () {
    if(!isCalled) {
      isCalled = true
      result = func(...arguments)
    }
    return result
  };
};

_.delay = function (func, wait) {
  setTimeout(...arguments)
};

_.includes = function (arr, target) {
  let result = false
  _.each(arr, (el) => {
    if (el === target) result = true
  })
  return result
};

_.every = function (arr, iteratee) {
  if(arr.length === 0) return true
  if(!iteratee){
    iteratee = _.identity;
  }
  for(let i=0; i < arr.length; i++){
    if(!iteratee(arr[i])){
      return false;
    }
  }
  return true;
};

_.some = function (arr, iteratee) {
  if(arr.length === 0) return false
  if(!iteratee){
    iteratee = _.identity;
  }
  for(let i=0; i < arr.length; i++){
    if(iteratee(arr[i])){
      return true;
    }
  }
  return false;
};

_.extend = function () {
  _.each(arguments, (el) => {
    for(let key in el) {
      arguments[0][key] = el[key]
    }
  })
      return arguments[0]// TODO: 여기에 코드를 작성합니다.
};

_.defaults = function () {
  _.each(arguments, (el) => {
    for(let key in el) {
      if(_.includes(Object.keys(arguments[0]),key) === false) {
      arguments[0][key] = el[key]
      }
      }
  })
      return arguments[0]
};

_.zip = function () {
  let arg = [...arguments]
  let maxLength = 0;
  _.each(arg, (el) => {
    if(el.length > maxLength) maxLength = el.length;
  })

  let result = [];
  for (let i=0; i<maxLength; i++) {
    let row = [];
    for (let j=0; j<arg.length; j++) {
      if (arg[j][i] === undefined) row.push(undefined);
      else row.push(arg[j][i]);
    }
    result.push(row);
  }
  return result;
};

_.zipStrict = function () {
  let arg = [...arguments]
  let minLength = arguments[0].length;
  _.each(arg, (el) => {
    if(el.length < minLength) minLength = el.length;
  })

  let result = [];
  for (let i=0; i<minLength; i++) {
    let row = [];
    for (let j=0; j<arg.length; j++) {
      row.push(arg[j][i]);
    }
    result.push(row);
  }
  return result;
};

_.intersection = function () {
  let result = [];
  _.each(arguments[0],(el)=> {
    let count =1;
    for (let j=1; j<arguments.length; j++) {
      if(_.includes(arguments[j],el) === false) {
        break;
      }
      count++
    }
    if (count === arguments.length) result.push(el)
  })
  return result
};

_.difference = function () {
  let result = [];
  _.each(arguments[0],(el)=> {
    let count =1;
    for (let j=1; j<arguments.length; j++) {
      if(_.includes(arguments[j],el)) {
        break;
      }
      count++
    }
    if (count === arguments.length) result.push(el)
  })
  return result
};

_.sortBy = function (arr, transform, order) {
  transform = transform || _.identity;
  let result = _.slice(arr)

  if (typeof transform(arr[0]) === 'number') {
    if (order === 1 || order === undefined) {
      result.sort((a,b) => transform(a)-transform(b));
    }
    else if (order === -1) {
      result.sort((a,b) => transform(b)-transform(a));
    }
  }
    
  else if (typeof transform(arr[0]) === 'string') {
    if (order === 1 || order === undefined) {
      result.sort((a,b) => {
        if (transform(a) < transform(b)) return -1;
        else if (transform(b) < transform(a)) return 1;
        else return 0;
      })
    }
    else if (order === -1) {
      result.sort((a,b) => {
        if (transform(a) > transform(b)) return -1;
        else if (transform(b) > transform(a)) return 1;
        else return 0;
      })
    }
  } 
  return result
};

_.shuffle = function (arr) {
  let arrCloned = arr.slice();
  for (let fromIdx = 0; fromIdx < arr.length; fromIdx++) {
    const toIdx = Math.floor(Math.random() * arr.length);
    // 아래 코드는 두 변수의 값을 교환합니다.
    let temp = arrCloned[fromIdx];
    arrCloned[fromIdx] = arrCloned[toIdx];
    arrCloned[toIdx] = temp;
  }
  return arrCloned;
};

마치며

기존에 사용했던 배열 메소드들을 직접 구현함으로써 작동원리를 이해하고 앞에서 만든 함수를 활용하면서 메소드들에 대해서 깊게 이해할 수 있었다. setTimeout를 통해서 비동기 챕터 부분을 예습할 수 있었고 arguments에 대해 이해하고 코드를 효율적으로 작성하는 법에 대해서 알 수 있는 시간이었다.

profile
개발자로 성장하기
post-custom-banner

0개의 댓글