언더스코어란?
코딩을 도와주는 자바스크립트 라이브러리로 매우 작은 용량에 80여가지의 function을 제공. 언더스코어 함수중에는 ES5, ES6를 거쳐 내장함수로 이미 지원하는 함수들이 있으므로 이미 브라우저 내장함수로 지원하고있다면 성능을 위해 내장함수를 이용하자.
용어설명
Context
bind로 묶어준다.
iteratee
반복처리 시키는 내용이다.
Context와 iteratee의 구분
// _.each(list, iteratee, [context]) _.each([1, 2, 3], alert);
=> alerts each number in turn...
_.each(, alert);
=> alerts each number value in turn... |
context를 지정하지 않았을 경우 list의 내용들이 iteratee를 통해 처리된다
_.each([1, 2, 3], function(num) {
// In here, "this" refers to the same Array as "someOtherArray"
alert( this[num] ); // num is the value from the array being iterated // so this[num] gets the item at the "num" index of // someOtherArray. }, someOtherArray); |
context가 있을 경우 this로 바인딩한다.
Collections Functions (Arrays or Objects)
each
각 요소에 iteratee를 적용한 결과를 리턴한다.
map
each와 비슷하지만 새로운 콜렉션을 만듬
특화 함수 : pluck
//_.map(list, iteratee, [context]) _.map([1, 2, 3], function(num){ return num * 3; }); => [3, 6, 9] _.map(, function(num, key){ return num * 3; }); => [3, 6, 9] _.map([[1, 2], [3, 4]], _.first); => [1, 3] |
index가 필요한 경우
reduce
입력받은 리스트로부터 하나의 결과를 작성함
memo는 reduction의 초기값 각각의 단계는 반드시 리턴값을 가져야하고
해당 리턴값이 재귀함수형식으로 계속 반복실행되어야 한다.
reduce 함수에서 iteratee 함수 사용시에 list가 배열이냐, 객체이냐에 따라 사용하는 인자가 다르다.
list가 배열일 경우, iteratee 함수의 인자(arguments)로 (memo, element, index, list)를 사용한다.
list가 객체일 경우, iteratee 함수의 인자(arguments)로 (memo, value, key, list)를 사용한다.
사용가능한경우 ES5 reduce를 사용
//_.reduce(list, iteratee, [memo], [context]) var sum = _.reduce([1, 2, 3],function(memo, num){ return memo + num; }, 0);
=> 6 |
reduce를 사용해 promise를 순차적으로 실행할 수 있다.
reduceRight
reduce를 오른쪽부터 이어붙임(right-associative)
사용가능한경우 es5 reuce를 이용
//_.reduceRight(list, iteratee, memo, [context]) var list = [[0, 1], [2, 3], [4, 5]]; var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); => [4, 5, 2, 3, 0, 1] |
비동기 함수 실행시키는 또 다른 예제.
find
iteratee의 반환값이 true인 첫번째 값을 반환
내부적으로 some을 호출함. some과 동일 하다고 할 수 있음.
//_.reduceRight(list, iteratee, memo, [context]) var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => 2
filter
find와는 다르게 true인 값을 리스트로 반환
특화함수 : where
반대함수 : reject
//_.filter(list, predicate, [context]) var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [2, 4, 6] |
where
list의 각 value에서 리스트에서 key-value값이 맞는 모든 properties를 반환
//_.where(list, properties) _.where(listOfPlays, ); => [, ] |
findWhere
//_.findWhere(list, properties)
where와 비슷하지만 처음값 하나만을 리턴한다.
reject
true면 포함 false면 뺌
filter와 반대
되도록 ES5 filter를 쓰도록하자.
//_.reject(list, predicate, [context]) var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [1, 3, 5] |
every
list내 모든게 참이여야 true를 반환
되도록 ES5 filter를 쓰도록하자.
//_.every(list, [predicate], [context]) _.every([2, 4, 5], function(num) { return num % 2 == 0; }); => false |
some
하나라도 조건을 만족하면 true!
//_.some(list, [predicate], [context]) _.some([null, 0, 'yes', false]); => true |
contains
lis에 해당 value값이 있으면 참 fromIndex를 넣을경우 해당 index에 값이 있어야 참
//_.contains(list, value, [fromIndex]) _.contains([1, 2, 3], 3); => true |
invoke
list에서 methodName을 정의하면 해당 method를 이용 return값 반환
//_.invoke(list, methodName, *arguments) _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); => [[1, 5, 7], [1, 2, 3]]
pluck
list에 propery 이름이 동일한 값을 받아 새로운 리스트를 만든다
맵의 특화 함수.. _.map(function (post){
return post.id })
_.pluck('id')
같음.
//_.pluck(list, propertyName) var stooges = [, , ]; _.pluck(stooges, 'name'); => ["moe", "larry", "curly"] |
max
최대값 반환
//_.max(list, [iteratee], [context]) var stooges = [, , ]; _.max(stooges, function(stooge){ return stooge.age; }); => ;
min
최소값 반환
//_.min(list, [iteratee], [context])
list가 undefine이거나 빈배열일 경우 Infinity를 반환함
sortBy
sorting 용
//_.sortBy(list, iteratee, [context])
var stooges = [, , ]; _.sortBy(stooges, 'name'); => [, , ];
groupBy
리턴값이 같은것끼리 array로 묶음
//_.groupBy(list, iteratee, [context]) _.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); }); => {1: [1.3], 2: [2.1, 2.4]} _.groupBy(['one', 'two', 'three'], 'length'); => {3: ["one", "two"], 5: ["three"]}
리턴값이 undefined 면 그룹의 키값도 undefined 가 됩니다.
indexBy
배열들을 index값을 기준으로 mapping
//_.indexBy(list, iteratee, [context]) var stooges = [, , ]; _.indexBy(stooges, 'age'); => { "40": , "50": , "60": } |
countBy
iteratee의 반환값의 개수를 반환
//_.countBy(list, iteratee, [context]) _.countBy([1, 2, 3, 4, 5], function(num) { return num % 2 == 0 ? 'even': 'odd'; }); =>
suuffle
섞어서 copy list 반환
//_.shuffle(list) _.shuffle([1, 2, 3, 4, 5, 6]); => [4, 1, 6, 3, 5, 2]
sample
랜덤하게 뽑는다.
//_.sample(list, [n]) _.sample([1, 2, 3, 4, 5, 6]); => 4 _.sample([1, 2, 3, 4, 5, 6], 3); => [1, 6, 2]
toArray
argument 들을 배열로 리턴
//_.toArray(list) (function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4); => [2, 3, 4]
list
배열 개수 반환
//_.size(list) _.size(); => 3
partition
array를 두 그룹으로 나눈다 그 후 만족하는 것과 만족하지 않는것을 각각
어레이로 묶는다.
//_.partition(array, predicate) _.partition([0, 1, 2, 3, 4, 5], isOdd); => [[1, 3, 5], [0, 2, 4]]
Array Functions
first
return first elelment
n이 있으면 앞에서 n번째
//_.initial(array, [n]) _.first([5, 4, 3, 2, 1]); => 5
initial
뒤에서 n번째
//_.last(array, [n]) _.last([5, 4, 3, 2, 1]); => 1
last
first와 동일하나 뒤에서부터
//_.last(array, [n]) _.last([5, 4, 3, 2, 1]); => 1
rest
index 앞까지 스킵하고 나머지 리턴.
//_.rest(array, [index]) _.rest([5, 4, 3, 2, 1]); => [4, 3, 2, 1]
compact
false,null,0,””빼고 다 반환
//_.compact(array) _.compact([0, 1, false, 2, '', 3]); => [1, 2, 3]
flatter
nesting을 어느 depth던 다 제거한다. shallow를 true로 주면 single level만
제거한다
//_.flatten(array, [shallow]) _.flatten([1, [2], [3, [[4]]]]); => [1, 2, 3, 4]; _.flatten([1, [2], [3, [[4]]]], true); => [1, 2, 3, [[4]]];
without
value값을 제외한 나머지값을 리턴
//_.without(array, *values) _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
union
전달 된 모든 배열의 각 개별 요소의 집합을 포함하는 배열을 제공한다.
//_.union(*arrays) _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2, 3, 101, 10]
intersection
교집합
//_.intersection(*arrays) _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2]
difference
차집합
//_.difference(array, *others) _.difference([1, 2, 3, 4, 5], [5, 2, 10]); => [1, 3, 4] |
uniq
중복이 없도록 한 배열을 제공한다. 배열이 이미 정렬되어있으면,
빠른 알고리즘을 사용할 수있는 옵션이있다.
//_.uniq(array, [isSorted], [iteratee]) _.uniq([1, 2, 1, 4, 1, 3]); => [1, 2, 4, 3]
zip
서로 상응하는 값끼리 묶어준다
//_.zip(*arrays) _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); => [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
unzip
zip의 반대개념
//_.unzip(array) _.unzip([["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]); => [['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]]
object
obj를 array로 변환해준다 단일값이나 key,value 쌍으로 가능
//_.object(list, [values]) _.object(['moe', 'larry', 'curly'], [30, 40, 50]); => _.object([['moe', 30], ['larry', 40], ['curly', 50]]); =>
indexOf
몇번째 value인지 sorting 되어있다면 isSorted 에 true를 주어 더욱 빠르게 검색가능
//_.indexOf(array, value, [isSorted]) _.indexOf([1, 2, 3], 2); => 1
lastIndexOf
indexOf의 reverse 버전
//_.lastIndexOf(array, value, [fromIndex]) _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); => 4
sortedIndex
sorting 되어있는 값을 기준으로 몇번째 인덱스에 넣을 수 있는지 반환
//_.sortedIndex(list, value, [iteratee], [context]) _.sortedIndex([10, 20, 30, 40, 50], 35); => 3 var stooges = [, ]; _.sortedIndex(stooges, , 'age'); => 1
findIndex
indexof와 비슷하나 predicate(true or flase)에서 true된 값을 기준으로 한다
//_.findIndex(array, predicate, [context]) _.findIndex([4, 6, 8, 12], isPrime); => -1 // not found _.findIndex([4, 6, 7, 12], isPrime); => 2 |
FindLastIndex
findIndex reverse version
//_.findLastIndex(array, predicate, [context]) var users = [{'id': 1, 'name': 'Bob', 'last': 'Brown'}, {'id': 2, 'name': 'Ted', 'last': 'White'}, {'id': 3, 'name': 'Frank', 'last': 'James'}, {'id': 4, 'name': 'Ted', 'last': 'Jones'}]; _.findLastIndex(users, { name: 'Ted' }); => 3 |
range
범위
//_.range([start], stop, [step]) _.range(10); => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] _.range(1, 11); => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] _.range(0, 30, 5); => [0, 5, 10, 15, 20, 25] _.range(0, -10, -1); => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] _.range(0); => [] |
Functional function
bind
바인딩
//_.bind(function, object, *arguments) var func = function(greeting){ return greeting + ': ' + this.name }; func = _.bind(func, , 'hi'); func(); => 'hi: moe'
bindAll
//_.bindAll(object, *methodNames) var buttonView = { label : 'underscore', onClick: function(){ alert('clicked: ' + this.label); }, onHover: function(){ console.log('hovering: ' + this.label); } }; _.bindAll(buttonView, 'onClick', 'onHover'); // When the button is clicked, this.label will have the correct value. jQuery('#underscore_button').on('click', buttonView.onClick);
partial
인자를 하나씩 넣을 수 있다. //_.partial(function, *arguments) var subtract = function(a, b) { return b - a; }; //subtract의 인자 2개 sub5 = _.partial(subtract, 5); //subtract의 첫 인자에 5를 셋팅한 값을 sub5에 넘김 sub5(20); //sub5 = subtract(5,argument) => 15 // Using a placeholder subFrom20 = _.partial(subtract, _, 20); //_로 막아놓기 가능 subFrom20(5); => 15
memoize
결과를 저장하는 것으로, 고비용의 함수를 memoize 화한다.
//_.memoize(function, [hashFunction]) var fibonacci = _.memoize(function(n) { return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2); });
delay
시간만큼 딜레이 후 실행시킴
//_.delay(function, wait, *arguments) var log = _.bind(console.log, console); _.delay(log, 1000, 'logged later'); => 'logged later' // Appears after one second.
defer
call stack의 내용이 전부 처리되면 실행시킨다
//_.defer(function, *arguments) _.defer(function(){ alert('deferred'); }); // Returns from the function before the alert runs.
throttled
호출되면 지정된 시간 내에 최대 1 번만 트리거되는 함수를 돌려 준다.
//_.throttle(function, wait, [options]) var throttled = _.throttle(updatePosition, 100); $(window).scroll(throttled);
debounce
연속 호출되는 한 트리거되지 않는 함수를 돌려준다.
예를들어 함수가 wiat만큼 기다리는동안 immediate의 return값을
받을경우 혹은 연속된 호출을 받을경우 호출이 시작된 시점부터 다시
카운팅 후 실행되게 된다.
//_.debounce(function, wait, [immediate]) var lazyLayout = _.debounce(calculateLayout, 300); $(window).resize(lazyLayout);
once
딱 한번만 실행
//_.once(function) var initialize = _.once(createApplication); initialize(); initialize(); // Application is only created once.
after
n번 호출된 이후에 실행한다.
//_.after(count, function) var renderNotes = _.after(notes.length, render); _.each(notes, function(note) { note.asyncSave(); }); // renderNotes is run once, after all notes have saved.
before
횟수제한
//_.before(count, function) var monthlyMeeting = _.before(3, askForRaise); monthlyMeeting(); monthlyMeeting(); monthlyMeeting(); // the result of any subsequent calls is the same as the second call
wrap
wrap을 씌워준다.
//.wrap(function, wrapper) var hello = function(name) { return "hello: " + name; }; hello = _.wrap(hello, function(func) { return "before, " + func("moe") + ", after"; }); hello(); => 'before, hello: moe, after'
negate
predicate를 0 혹은 1로 반환하는 것같다.
//_.negate(predicate) var isFalsy = _.negate(Boolean); _.find([-2, -1, 0, 1, 2], isFalsy); => 0
compose
함수 목록에서 각각의 함수가 거기에 계속되는 함수의 반환 값을 인수에 취하는 합성 함수를 돌려 준다.
f(), g(), and h() produces f(g(h())).
//_.compose(*functions) var greet = function(name){ return "hi: " + name; }; var exclaim = function(statement){ return statement.toUpperCase() + "!"; }; var welcome = _.compose(greet, exclaim); welcome('moe'); => hi! moe
Object Functions
keys
obj의 key 반환
//_.keys(object) _.keys(); => ["one", "two", "three"] |
allKeys
obj의 모든 inherited properties 출력
//_.allKeys(object) function Stooge(name) { this.name = name; } Stooge.prototype.silly = true; _.allKeys(new Stooge("Moe")); => ["name", "silly"]
values
value 반환
=> [1, 2, 3] |
mapObject
예제를 보자
//_.mapObject(object, iteratee, [context]) _.mapObject(, function(val, key) { return val + 5; });
paris
obj to list
//_.pairs(object) _.pairs(); => [["one", 1], ["two", 2], ["three", 3]]
invert
obj의 key값과 value값을 바꿔준다.
extend
예제 destination에서 source로 값을 복사 하고 desinatio을 리턴 (두 값을 합쳐주는데 같은 필드가 있으면 뒤의 것을 사용한다는 뜻)
_.extend(detination, *srouce)
_.extend(, ); => |
pick
keys들로 필터링 해준다.
_.pick(object, *keys)
=> key가 없으면 반환값이 포함되지 않는다.
=> 반대 동작(blacklist)는 omit를 사용하면 된다.
chain
'WEB' 카테고리의 다른 글
자바스크립트+제이쿼리 (0) | 2016.05.21 |
---|---|
스프링 입문을 위한 자바 객체지향의 원리와 이해 (0) | 2016.04.15 |
크롬에서 request, response header 확인하기. (0) | 2016.04.14 |