2020. 12. 30 / Underbar Test (2/2)

32287 단어 TILTIL

어제 열심히 복습한 보람이 있었다.

마지막에 _.sort 함수때문에 애먹긴 했지만 그 전까진 나름 선방했다구...

여튼 오늘은 part 2 다.

advanced corse인 part3도 있긴 하지만 일단 지금은 패스.


_.includes

_.includes = function (arr, target) {

  let result = false;

  _.each(arr, function(item) { 
    if(item === target) { 
      result = true; 
    }
  })

  return result;
};
  1. arr 내부에 target 이 포함되어 있는지 아닌지를 판별해주는 함수.

  2. 최초에 result값을 false 로 설정해놓고, arr에 target 이 있으면 값이 true 로 바뀌는 로직이다. 어제 만들어 놓은 _.each 함수를 이용해 arr 요소를 순회하는 것이 특징이다.


_.every

_.every = function (arr, iteratee) {
  
  let result = true;

  _.each(arr, function(item) {
    if(iteratee) {
      if(!iteratee(item)) {
        result = false;
      } 
    } else {
      if(!item) {
        result = false;
      }
    }
  })

  return result;
};
  1. arr의 요소들에 iteratee 함수를 적용한 결과가 모두 true이면 true, 아니면 false 를 반환하는 함수.

  2. 초기 result 값을 true 로 설정해놓고, arr 의 요소 중 하나라도 false 면 result값이 false 로 변한다.

  3. iteratee 함수가 전달되지 않은 경우에는 요소 자체의 boolean 값을 판단하는 것이 특징.
    iteratee 함수가 전달되지 않은 경우는 (!iteratee) 로 표현된다.


_.some

_.some = function (arr, iteratee) {
  
  let result = false;

  _.each(arr, function(item) {
    if(iteratee) {
      if(iteratee(item)) {
        result = true;
      }
    } else if(item) {
      result = true;
    }
  })

  return result;
};
  • iteratee 함수를 통과한 arr의 요소들 중 하나라도 true 면 true 를 반환하는 함수.
    로직이 바로 위의 _.every와 같기 때문에 분설은 생략.

_.extend

_.extend = function (...args) {

  _.each(args, function(obj) {       // obj 는 args 배열에 담긴 객체들을 의미한다.
    for(let key in obj) {            // obj 들의 key 를 순회한다.
      args[0][key] = item[key];      // 첫 객체에 다른 객체의 key: value 를 저장
    }
  });

  return args[0];
};
  1. 객체들을 전달받아 객체의 프로퍼티들을 첫 번째 객체에 순서대로 결합해서 첫 번째 객체를 리턴하는 함수.

  2. 인자로 전달되는 객체들을 나머지 매개변수 처리하는데, 각 객체들이 배열에 담겨 전달되며, args 변수를 사용함으로써 이 배열을 참조할 수 있다.


_.default

_.defaults = function (...args) {
  _.each(args, function(obj){ // obj 는 args 배열의 요소인 각 객체.

    for(let key in obj){ 	  // key 는 args 배열의 요소인 객체 obj 가 가지고 있는 key
      if(!_.includes(Object.keys(args[0]), key)){  // 순회하는 key를 args[0]가 포함하고 있지 않으면
        args[0][key] = obj[key];
      }
    }
  });

  return args[0];
};
  1. _.extend 와 똑같이 동작하는데, 첫 번째 객체에 중복되는 키가 이미 있으면 그 프로퍼티는 담지 않는다.

  2. _.includes 함수를 사용해 key 중복여부를 판정하는 것이 핵심이다.


_.zip

_.zip = function(...args) {
  let maxArr = [];
  let maxLength;

  _.each(args, function(item) {
    if(item.length > maxArr.length) {
      maxArr = item;
    }
  })
  maxLength = maxArr.length;
  
// 인자로 들어온 배열들 중 가장 긴 배열을 찾아, 그 길이를 maxLength 함수에 할당했다.

let result = [];
  for(let i=0; i < maxLength; i++){
    let newArr = [];
      for(let j=0; j < args.length; j++){
        newArr.push(args[j][i])
      }
    result.push(newArr);
  }
  
// j 는 배열을 순회하고, i는 배열의 인덱스를 순회한다.
// i값이 안쪽 for문으로 들어와 인덱스를 고정시키면 j로 배열을 순회하며 같은 인덱스 요소들을 같은 배열로 묶는다.
// 같은 인덱스 요소들로 구성된 배열 newArr 배열을 result 배열의 요소로 푸쉬한다.

return result;
};
  1. 여러개의 배열을 입력받아, 같은 index끼리 묶어 새로운 배열을 만들어 리턴하는 함수. 어째 점점 복잡해진다. 인자로 전달되는 배열들의 길이는 제각각이며, 새 배열은 가장 긴 배열의 길이를 갖는다.

  2. 로직은 크게 두 덩이로 나뉜다. 1) 가장 긴 배열을 찾고 2) 인덱스끼리 묶어 새 배열에 푸쉬하고.
    자세한건 코드 내부의 주석을 참조.


_.zipstrict

_.zipStrict = function (...args) {
  let minArr = args[0];
  let minLength;

  _.each(args, function(item) {
    if(item.length < minArr.length) {
      minArr = item;
    }
  })
  maxLength = maxArr.length;

  let result = [];
  for(let i=0; i < maxLength; i++){
    let newArr = [];
      for(let j=0; j < args.length; j++){
        newArr.push(args[j][i])
      }
    result.push(newArr);
  }

return result;
};
  1. zip 함수와의 차이는 이번에는 가장 짧은 배열을 기준으로 새로운 배열의 길이가 구성되어 리턴된다는 것이다.

  2. 두 번째 로직은 동일하고, 배열의 길이를 설정하는 즉 첫 번째 로직만 살짝 수정해주면 제대로 작동한다.


intersection

_.intersection = function(...args) {
  let arr = [];

  for(let i = 0; i < args[0].length; i++){
    let boo = true; 

    for(let j = 1; j < args.length; j++){    // 두 번째 배열부터 비교해야 하므로 j는 1에서 시작.
      if(!_.includes(args[j], args[0][i])){  // j번째 배열에 args[0]배열의 i번째 요소가 없다면
        boo = false; 
      }
    }
    
    if(boo) {
      arr.push(args[0][i]);
    }
  }

  return arr;
};
  1. 여러개의 배열을 전달받아, 교집합 배열을 리턴하는 함수.

  2. 첫 번째 배열의 요소들을 기준으로, 각 요소가 다른 배열들에도 전부 존재하는지 판단해 true면 arr에 푸쉬.

  3. true값을 가지는 boo 를 선언해놓고 한 번도 13번줄 if문을 통과하지 않았으면 푸쉬하도록 짜봤다.


_.difference

_.difference = function (...args) {
  let arr = [];

  for(let i = 0; i < args[0].length; i++){
    let boo = true; 
    
    for(let j = 1; j < args.length; j++){
      if(_.includes(args[j], args[0][i])){
        boo = false; 
      }
    }
    
    if(boo) {
      arr.push(args[0][i]);
    }
  }
  
  return arr;
};
  • 이번에는 차집합 배열을 리턴하는 함수.
    위 intersection 함수와 구조가 완전히 동일하며, if문의 조건만 수정되었다.

_.sort

_.sortBy = function (arr, transform, order) {

  const newArr = _.map(arr, _.identity);
  order = order || 1; // order 값이 전달되지 않았으면 1로 하겠다.
  transform = transform || _.identity; // transform 함수가 전달되지 않았으면 _.identity를 적용하겠다.
  				       // 여기서 _.idnetity 는 전달된 인자를 그대로 리턴해주는 함수. 

  newArr.sort(function (a, b) {
    if (transform(a) < transform(b)) {
      return -1 * order 
    } else {
      return order
    }
  })

  return newArr;
};
  1. arr 요소들에 transform 함수를 적용한 결과를 기준으로 배열을 정렬해서 리턴하는 함수.

  2. transform 함수가 전달되지 않으면 arr 요소를 그냥 정렬하면 되고, order 전달되지 않았거나 1 이면 오름차순, -1 이면 내림차순으로 정렬한다.


좋은 웹페이지 즐겨찾기