Lodash는 JS util들을 제공하는 라이브러리이다. 개발 할 때 유용하게 사용할 수 있는게 많은데, 제대로 공식문서를 읽어본적이 없어서 쓸만한것들 정리해보고자 한다.
기준 : 한눈에 봤을 때 기존의 JS 메소드로 구현하면 코드수가 길어질 것 같은 것들 위주로 정리했다.
ref) 공식문서 : https://lodash.com/docs/4.17.15
(4.17.15 버전)
_.chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
_.chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]
첫번째 array에서 2번째 array에 들어있는 값을 제외한 값을 반환.
filter와 include로 구현가능하지만, 이게 코드가 더 깔끔하긴하다.
_.difference([2, 1], [2, 3]);
// => [1]
differenceBy는 iteratee인수를 받는데, array끼리 compare하는 기준 funciton을 인자로 받는다.
첫번째 배열에서 두번째배열을 3번째 iteratee로 제외한 결과값을 반환함.
iteratee: 비교의 기준이 될 함수 또는 속성. 각 배열의 요소에 이 함수를 적용한 후 결과값을 비교함.
_.differenceBy(array, [values], [iteratee])
_.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
// => [1.2]
// The `_.property` iteratee shorthand.
_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
// => [{ 'x': 2 }]
differenceWith는 커스텀 비교 함수를 사용하여 두 배열의 요소를 비교하고 차이를 구한다.
comparator: 두 값을 비교하는 함수. true를 반환하면 해당 값은 차이에서 제외됨.
const objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
const others = [{ 'x': 1, 'y': 2 }];
const result = _.differenceWith(objects, others, _.isEqual);
console.log(result); // [{ 'x': 2, 'y': 1 }]
predicate값이 falsey한 값을 return 할때까지 array에서 pop이나 shift를 진행한다.
while문 + 조건문으로 구현 가능한데, 쓰면 더 깔끔해질듯.
var users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
];
_.dropRightWhile(users, function(o) { return !o.active; });
// => objects for ['barney']
// The `_.matches` iteratee shorthand.
_.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
// => objects for ['barney', 'fred']
// The `_.matchesProperty` iteratee shorthand.
_.dropRightWhile(users, ['active', false]);
// => objects for ['barney']
// The `_.property` iteratee shorthand.
_.dropRightWhile(users, 'active');
// => objects for ['barney', 'fred', 'pebbles']
_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]
_.fromPairs([['a', 1], ['b', 2]]);
// => { 'a': 1, 'b': 2 }
두 배열의 교집합을 구해서 배열로 반환한다.
By, With 차이는 커스텀함수인지, iteratee인지임
_.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
// => [2.1]
// The `_.property` iteratee shorthand.
_.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
// => [{ 'x': 1 }]
_.union([2], [1, 2]);
// => [2, 1]
_.unionBy([2.1], [1.2, 2.3], Math.floor);
// => [2.1, 1.2]
// The `_.property` iteratee shorthand.
_.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
// => [{ 'x': 1 }, { 'x': 2 }]
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.unionWith(objects, others, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
_.uniq([2, 1, 2]);
// => [2, 1]
_.uniqBy([2.1, 1.2, 2.3], Math.floor);
// => [2.1, 1.2]
// The `_.property` iteratee shorthand.
_.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
// => [{ 'x': 1 }, { 'x': 2 }]
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
// => [['a', 1, true], ['b', 2, false]]
_.unzip(zipped);
// => [['a', 'b'], [1, 2], [true, false]]
collection (Array|Object): The collection to iterate over. => 이터레이터가 있는 collection들에 적용 가능한 메소드이다.
JS에서 Collection 은 다음과 같다
Indexed Collection - Arrays, Typed Array
Keyed Collection - Objects, Map, Set, Weak Map, Weak Set
_.countBy([6.1, 4.2, 6.3], Math.floor);
// => { '4': 1, '6': 2 }
// The `_.property` iteratee shorthand.
_.countBy(['one', 'two', 'three'], 'length');
// => { '3': 2, '5': 1 }
코드를 입력하세요
_.forEachRight([1, 2], function(value) {
console.log(value);
});
// => Logs `2` then `1`.
_.groupBy([6.1, 4.2, 6.3], Math.floor);
// => { '4': [4.2], '6': [6.1, 6.3] }
// The `_.property` iteratee shorthand.
_.groupBy(['one', 'two', 'three'], 'length');
// => { '3': ['one', 'two'], '5': ['three'] }
var array = [
{ 'dir': 'left', 'code': 97 },
{ 'dir': 'right', 'code': 100 }
];
_.keyBy(array, function(o) {
return String.fromCharCode(o.code);
});
// => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
_.keyBy(array, 'dir');
// => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 34 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 36 }
];
// Sort by `user` in ascending order and by `age` in descending order.
_.orderBy(users, ['user', 'age'], ['asc', 'desc']);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
_.sample([1, 2, 3, 4]);
// => 2
_.sampleSize([1, 2, 3], 2);
// => [3, 1]
_.sampleSize([1, 2, 3], 4);
// => [2, 3, 1]
_.shuffle([1, 2, 3, 4]);
// => [4, 1, 3, 2]
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 34 }
];
_.sortBy(users, [function(o) { return o.user; }]);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
_.sortBy(users, ['user', 'age']);
// => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
debounced된 function을 만든다.
wait된 시간 이후에 function 이 invoke되록 새로 debounced 된 function을 반환
특정 시점 이후에 함수가 호출되는게 debounce
// Avoid costly calculations while the window size is in flux.
jQuery(window).on('resize', _.debounce(calculateLayout, 150));
// Invoke `sendMail` when clicked, debouncing subsequent calls.
jQuery(element).on('click', _.debounce(sendMail, 300, {
'leading': true,
'trailing': false
}));
// Ensure `batchLog` is invoked once after 1 second of debounced calls.
var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
var source = new EventSource('/stream');
jQuery(source).on('message', debounced);
// Cancel the trailing debounced invocation.
jQuery(window).on('popstate', debounced.cancel);
_.delay(function(text) {
console.log(text);
}, 1000, 'later');
// => Logs 'later' after one second.
var initialize = _.once(createApplication);
initialize();
initialize();
// => `createApplication` is invoked once
// Avoid excessively updating the position while scrolling.
jQuery(window).on('scroll', _.throttle(updatePosition, 100));
// Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
jQuery(element).on('click', throttled);
// Cancel the trailing throttled invocation.
jQuery(window).on('popstate', throttled.cancel);