코드 스테이츠의 새로운 과제를 진행하면서 자바스크립트 유틸리티 라이브러리 underscore와 underscore의 몇몇 함수들을 직접 구현해보았다. Lodash, Underscore.js 같은 라이브러리의 코어 디자인은 부수 효과(Side-effect)가 없는 즉 외부 상태를 바꾸지 않는 순수 함수를 사용하는 함수들로 구성되어있다. 아직 함수형 프로그래밍이 많이 낯설지만, 과제를 통해 부수효과가 없는 함수들을 직접 구현해보니, 좀더 함수형 프로그래밍에 한걸음 가까워진 기분이 들었다 :) 구현했던 함수들을 전부 글에 담으면 글이 너무 길어질것 같아서 구현하는데 중요하다고 생각한 함수들만 담았다.
_.filter는 두번째 인자인 test 함수를 통과하는 모든 요소를 담은 새로운 배열을 리턴한다. 자바 스크립트의 filter와 비슷하다.
‣ // example const isLargerThanEqualSix = function (ele) { return ele.length >= 6; }; const arr = ['hello', 'codestates', 'javascript', 'sw', 'web']; const longs = _.filter(arr, isLargerThanEqualSix); expect(longs).to.eql(['codestates', 'javascript']);
_.uniq는 주어진 배열의 유니크 값을 갖는 새로운 배열을 리턴한다.
‣ // example const arr = [1, 2, 1, 3, 1, '3', 4, '1', 2]; expect(_.uniq(arr)).to.eql([1, 2, 3, '3', 4, '1']);
_.map은 iteratee를 배열의 각 요소에 적용한 결과를 담은 새로운 배열을 리턴한다. 즉 배열의 각 요소를 iteratee의 결과로 mapping한다. (기능적 으로 자바스크립트의 map()과 동일하다)
‣ // example const squared = _.map([1, 2, 3], function (num) { return num ** 2; }); expect(squared).to.eql([1, 4, 9]);
_.reduce는 배열을 순회하며 각 요소에 iteratee 함수를 적용하고 그 결과값을 계속해서 누적(accumulate)하며, 최종적으로 누적된 결과값을 리턴합니다.
‣ // example const orderTraversed = []; const result = _.reduce( [1, 2, 3, 4], function (left, item) { orderTraversed.push(item); return left - item; }, 12 ); expect(result).to.equal(2); expect(orderTraversed).to.eql([1, 2, 3, 4]);
_.sortBy는 배열의 각 요소에 함수 transform을 적용하여 얻은 결과를 기준으로 정렬한다.
transform이 전달되지 않은 경우, 배열의 요소 자체끼리 비교를 하며, 세 번째 인자인 order는 정렬의 방향을 나타낸다. order가 생략되거나 1을 입력받은 경우 오름차순, -1을 입력받은 경우 내림차순으로 정렬한다.‣ // example const bias = [ { name: 'jin', height: 179, age: 27 }, { name: 'jimin', height: 178, age: 24 }, { name: 'suga', age: 26 }, ]; const byAgeDes = _.sortBy( bias, function (person) { return person.age; }, -1 ); expect(_.pluck(byAgeDes, 'name')).to.eql(['jin', 'suga', 'jimin']);
_.flatten은 다차원 배열을 입력받아, 1차원 배열로 변환하여 리턴한다. 재귀와 이중 reduce를 이용해서 풀었는데, 분명 더 좋은 방법이 있을거같다.
‣ // example
const nestedArray = [1, [2], [3, [[[4]]]], 5, [6, [7, [8]]]];
expect(_.flatten(nestedArray)).to.eql([1, 2, 3, 4, 5, 6, 7, 8]);
-오늘자 요약- (과제 시작부터 끝까지 쉬지않고 열심히 달렸다:)