/ * *
* @ license
* Lo - Dash 1.3 . 1 ( Custom Build ) < http : //lodash.com/>
* Build : ` lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js `
* Copyright 2012 - 2013 The Dojo Foundation < http : //dojofoundation.org/>
* Based on Underscore . js 1.5 . 1 < http : //underscorejs.org/LICENSE>
* Copyright 2009 - 2013 Jeremy Ashkenas , DocumentCloud and Investigative Reporters & Editors
* Available under MIT license < http : //lodash.com/license>
* /
; ( function ( window ) {
/** Used as a safe reference for `undefined` in pre ES5 environments */
var undefined ;
/** Used to generate unique IDs */
var idCounter = 0 ;
/** Used internally to indicate various things */
var indicatorObject = { } ;
/** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
var keyPrefix = + new Date + '' ;
/** Used to match "interpolate" template delimiters */
var reInterpolate = /<%=([\s\S]+?)%>/g ;
/** Used to ensure capturing order of template delimiters */
var reNoMatch = /($^)/ ;
/** Used to match unescaped characters in compiled string literals */
var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g ;
/** `Object#toString` result shortcuts */
var argsClass = '[object Arguments]' ,
arrayClass = '[object Array]' ,
boolClass = '[object Boolean]' ,
dateClass = '[object Date]' ,
funcClass = '[object Function]' ,
numberClass = '[object Number]' ,
objectClass = '[object Object]' ,
regexpClass = '[object RegExp]' ,
stringClass = '[object String]' ;
/** Used to determine if values are of the language type Object */
var objectTypes = {
'boolean' : false ,
'function' : true ,
'object' : true ,
'number' : false ,
'string' : false ,
'undefined' : false
} ;
/** Used to escape characters for inclusion in compiled string literals */
var stringEscapes = {
'\\' : '\\' ,
"'" : "'" ,
'\n' : 'n' ,
'\r' : 'r' ,
'\t' : 't' ,
'\u2028' : 'u2028' ,
'\u2029' : 'u2029'
} ;
/** Detect free variable `exports` */
var freeExports = objectTypes [ typeof exports ] && exports ;
/** Detect free variable `module` */
var freeModule = objectTypes [ typeof module ] && module && module . exports == freeExports && module ;
/** Detect free variable `global` from Node.js or Browserified code and use it as `window` */
var freeGlobal = objectTypes [ typeof global ] && global ;
if ( freeGlobal && ( freeGlobal . global === freeGlobal || freeGlobal . window === freeGlobal ) ) {
window = freeGlobal ;
}
/*--------------------------------------------------------------------------*/
/ * *
* The base implementation of ` _.indexOf ` without support for binary searches
* or ` fromIndex ` constraints .
*
* @ private
* @ param { Array } array The array to search .
* @ param { Mixed } value The value to search for .
* @ param { Number } [ fromIndex = 0 ] The index to search from .
* @ returns { Number } Returns the index of the matched value or ` -1 ` .
* /
function baseIndexOf ( array , value , fromIndex ) {
var index = ( fromIndex || 0 ) - 1 ,
length = array ? array . length : 0 ;
while ( ++ index < length ) {
if ( array [ index ] === value ) {
return index ;
}
}
return - 1 ;
}
/ * *
* Used by ` sortBy ` to compare transformed ` collection ` elements , stable sorting
* them in ascending order .
*
* @ private
* @ param { Object } a The object to compare to ` b ` .
* @ param { Object } b The object to compare to ` a ` .
* @ returns { Number } Returns the sort order indicator of ` 1 ` or ` -1 ` .
* /
function compareAscending ( a , b ) {
var ac = a . criteria ,
bc = b . criteria ;
// ensure a stable sort in V8 and other engines
// http://code.google.com/p/v8/issues/detail?id=90
if ( ac !== bc ) {
if ( ac > bc || typeof ac == 'undefined' ) {
return 1 ;
}
if ( ac < bc || typeof bc == 'undefined' ) {
return - 1 ;
}
}
// The JS engine embedded in Adobe applications like InDesign has a buggy
// `Array#sort` implementation that causes it, under certain circumstances,
// to return the same value for `a` and `b`.
// See https://github.com/jashkenas/underscore/pull/1247
return a . index - b . index ;
}
/ * *
* Used by ` template ` to escape characters for inclusion in compiled
* string literals .
*
* @ private
* @ param { String } match The matched character to escape .
* @ returns { String } Returns the escaped character .
* /
function escapeStringChar ( match ) {
return '\\' + stringEscapes [ match ] ;
}
/ * *
* A no - operation function .
*
* @ private
* /
function noop ( ) {
// no operation performed
}
/*--------------------------------------------------------------------------*/
/ * *
* Used for ` Array ` method references .
*
* Normally ` Array.prototype ` would suffice , however , using an array literal
* avoids issues in Narwhal .
* /
var arrayRef = [ ] ;
/** Used for native method references */
var objectProto = Object . prototype ;
/** Used to restore the original `_` reference in `noConflict` */
var oldDash = window . _ ;
/** Used to detect if a method is native */
var reNative = RegExp ( '^' +
String ( objectProto . valueOf )
. replace ( /[.*+?^${}()|[\]\\]/g , '\\$&' )
. replace ( /valueOf|for [^\]]+/g , '.+?' ) + '$'
) ;
/** Native method shortcuts */
var ceil = Math . ceil ,
floor = Math . floor ,
hasOwnProperty = objectProto . hasOwnProperty ,
push = arrayRef . push ,
toString = objectProto . toString ,
unshift = arrayRef . unshift ;
/* Native method shortcuts for methods with the same name as other `lodash` methods */
var nativeBind = reNative . test ( nativeBind = toString . bind ) && nativeBind ,
nativeCreate = reNative . test ( nativeCreate = Object . create ) && nativeCreate ,
nativeIsArray = reNative . test ( nativeIsArray = Array . isArray ) && nativeIsArray ,
nativeIsFinite = window . isFinite ,
nativeIsNaN = window . isNaN ,
nativeKeys = reNative . test ( nativeKeys = Object . keys ) && nativeKeys ,
nativeMax = Math . max ,
nativeMin = Math . min ,
nativeRandom = Math . random ,
nativeSlice = arrayRef . slice ;
/** Detect various environments */
var isIeOpera = reNative . test ( window . attachEvent ) ,
isV8 = nativeBind && ! /\n|true/ . test ( nativeBind + isIeOpera ) ;
/*--------------------------------------------------------------------------*/
/ * *
* Creates a ` lodash ` object which wraps the given value to enable method
* chaining .
*
* In addition to Lo - Dash methods , wrappers also have the following ` Array ` methods :
* ` concat ` , ` join ` , ` pop ` , ` push ` , ` reverse ` , ` shift ` , ` slice ` , ` sort ` , ` splice ` ,
* and ` unshift `
*
* Chaining is supported in custom builds as long as the ` value ` method is
* implicitly or explicitly included in the build .
*
* The chainable wrapper functions are :
* ` after ` , ` assign ` , ` bind ` , ` bindAll ` , ` bindKey ` , ` chain ` , ` compact ` ,
* ` compose ` , ` concat ` , ` countBy ` , ` createCallback ` , ` curry ` , ` debounce ` ,
* ` defaults ` , ` defer ` , ` delay ` , ` difference ` , ` filter ` , ` flatten ` , ` forEach ` ,
* ` forEachRight ` , ` forIn ` , ` forInRight ` , ` forOwn ` , ` forOwnRight ` , ` functions ` ,
* ` groupBy ` , ` indexBy ` , ` initial ` , ` intersection ` , ` invert ` , ` invoke ` , ` keys ` ,
* ` map ` , ` max ` , ` memoize ` , ` merge ` , ` min ` , ` object ` , ` omit ` , ` once ` , ` pairs ` ,
* ` partial ` , ` partialRight ` , ` pick ` , ` pluck ` , ` pull ` , ` push ` , ` range ` , ` reject ` ,
* ` remove ` , ` rest ` , ` reverse ` , ` shuffle ` , ` slice ` , ` sort ` , ` sortBy ` , ` splice ` ,
* ` tap ` , ` throttle ` , ` times ` , ` toArray ` , ` transform ` , ` union ` , ` uniq ` , ` unshift ` ,
* ` unzip ` , ` values ` , ` where ` , ` without ` , ` wrap ` , and ` zip `
*
* The non - chainable wrapper functions are :
* ` clone ` , ` cloneDeep ` , ` contains ` , ` escape ` , ` every ` , ` find ` , ` findIndex ` ,
* ` findKey ` , ` findLast ` , ` findLastIndex ` , ` findLastKey ` , ` has ` , ` identity ` ,
* ` indexOf ` , ` isArguments ` , ` isArray ` , ` isBoolean ` , ` isDate ` , ` isElement ` ,
* ` isEmpty ` , ` isEqual ` , ` isFinite ` , ` isFunction ` , ` isNaN ` , ` isNull ` , ` isNumber ` ,
* ` isObject ` , ` isPlainObject ` , ` isRegExp ` , ` isString ` , ` isUndefined ` , ` join ` ,
* ` lastIndexOf ` , ` mixin ` , ` noConflict ` , ` parseInt ` , ` pop ` , ` random ` , ` reduce ` ,
* ` reduceRight ` , ` result ` , ` shift ` , ` size ` , ` some ` , ` sortedIndex ` , ` runInContext ` ,
* ` template ` , ` unescape ` , ` uniqueId ` , and ` value `
*
* The wrapper functions ` first ` and ` last ` return wrapped values when ` n ` is
* provided , otherwise they return unwrapped values .
*
* @ name _
* @ constructor
* @ category Chaining
* @ param { Mixed } value The value to wrap in a ` lodash ` instance .
* @ returns { Object } Returns a ` lodash ` instance .
* @ example
*
* var wrapped = _ ( [ 1 , 2 , 3 ] ) ;
*
* // returns an unwrapped value
* wrapped . reduce ( function ( sum , num ) {
* return sum + num ;
* } ) ;
* // => 6
*
* // returns a wrapped value
* var squares = wrapped . map ( function ( num ) {
* return num * num ;
* } ) ;
*
* _ . isArray ( squares ) ;
* // => false
*
* _ . isArray ( squares . value ( ) ) ;
* // => true
* /
function lodash ( value ) {
return ( value instanceof lodash )
? value
: new lodashWrapper ( value ) ;
}
/ * *
* A fast path for creating ` lodash ` wrapper objects .
*
* @ private
* @ param { Mixed } value The value to wrap in a ` lodash ` instance .
* @ param { Boolean } chainAll A flag to enable chaining for all methods
* @ returns { Object } Returns a ` lodash ` instance .
* /
function lodashWrapper ( value , chainAll ) {
this . _ _chain _ _ = ! ! chainAll ;
this . _ _wrapped _ _ = value ;
}
// ensure `new lodashWrapper` is an instance of `lodash`
lodashWrapper . prototype = lodash . prototype ;
/ * *
* An object used to flag environments features .
*
* @ static
* @ memberOf _
* @ type Object
* /
var support = { } ;
( function ( ) {
var object = { '0' : 1 , 'length' : 1 } ;
/ * *
* Detect if ` Function#bind ` exists and is inferred to be fast ( all but V8 ) .
*
* @ memberOf _ . support
* @ type Boolean
* /
support . fastBind = nativeBind && ! isV8 ;
/ * *
* Detect if ` Array#shift ` and ` Array#splice ` augment array - like objects correctly .
*
* Firefox < 10 , IE compatibility mode , and IE < 9 have buggy Array ` shift() `
* and ` splice() ` functions that fail to remove the last element , ` value[0] ` ,
* of array - like objects even though the ` length ` property is set to ` 0 ` .
* The ` shift() ` method is buggy in IE 8 compatibility mode , while ` splice() `
* is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
*
* @ memberOf _ . support
* @ type Boolean
* /
support . spliceObjects = ( arrayRef . splice . call ( object , 0 , 1 ) , ! object [ 0 ] ) ;
} ( 1 ) ) ;
/ * *
* By default , the template delimiters used by Lo - Dash are similar to those in
* embedded Ruby ( ERB ) . Change the following template settings to use alternative
* delimiters .
*
* @ static
* @ memberOf _
* @ type Object
* /
lodash . templateSettings = {
/ * *
* Used to detect ` data ` property values to be HTML - escaped .
*
* @ memberOf _ . templateSettings
* @ type RegExp
* /
'escape' : /<%-([\s\S]+?)%>/g ,
/ * *
* Used to detect code to be evaluated .
*
* @ memberOf _ . templateSettings
* @ type RegExp
* /
'evaluate' : /<%([\s\S]+?)%>/g ,
/ * *
* Used to detect ` data ` property values to inject .
*
* @ memberOf _ . templateSettings
* @ type RegExp
* /
'interpolate' : reInterpolate ,
/ * *
* Used to reference the data object in the template text .
*
* @ memberOf _ . templateSettings
* @ type String
* /
'variable' : ''
} ;
/*--------------------------------------------------------------------------*/
/ * *
* The base implementation of ` _.createCallback ` without support for creating
* "_.pluck" or "_.where" style callbacks .
*
* @ private
* @ param { Mixed } [ func = identity ] The value to convert to a callback .
* @ param { Mixed } [ thisArg ] The ` this ` binding of the created callback .
* @ param { Number } [ argCount ] The number of arguments the callback accepts .
* @ returns { Function } Returns a callback function .
* /
function baseCreateCallback ( func , thisArg , argCount ) {
if ( typeof func != 'function' ) {
return identity ;
}
// exit early if there is no `thisArg`
if ( typeof thisArg == 'undefined' ) {
return func ;
}
switch ( argCount ) {
case 1 : return function ( value ) {
return func . call ( thisArg , value ) ;
} ;
case 2 : return function ( a , b ) {
return func . call ( thisArg , a , b ) ;
} ;
case 3 : return function ( value , index , collection ) {
return func . call ( thisArg , value , index , collection ) ;
} ;
case 4 : return function ( accumulator , value , index , collection ) {
return func . call ( thisArg , accumulator , value , index , collection ) ;
} ;
}
return bind ( func , thisArg ) ;
}
/ * *
* The base implementation of ` _.flatten ` without support for callback
* shorthands or ` thisArg ` binding .
*
* @ private
* @ param { Array } array The array to flatten .
* @ param { Boolean } [ isShallow = false ] A flag to restrict flattening to a single level .
* @ param { Boolean } [ isArgArrays = false ] A flag to restrict flattening to arrays and ` arguments ` objects .
* @ param { Number } [ fromIndex = 0 ] The index to start from .
* @ returns { Array } Returns a new flattened array .
* /
function baseFlatten ( array , isShallow , isArgArrays , fromIndex ) {
var index = ( fromIndex || 0 ) - 1 ,
length = array ? array . length : 0 ,
result = [ ] ;
while ( ++ index < length ) {
var value = array [ index ] ;
// recursively flatten arrays (susceptible to call stack limits)
if ( value && typeof value == 'object' && ( isArray ( value ) || isArguments ( value ) ) ) {
push . apply ( result , isShallow ? value : baseFlatten ( value , isShallow , isArgArrays ) ) ;
} else if ( ! isArgArrays ) {
result . push ( value ) ;
}
}
return result ;
}
/ * *
* The base implementation of ` _.isEqual ` , without support for ` thisArg ` binding ,
* that allows partial "_.where" style comparisons .
*
* @ private
* @ param { Mixed } a The value to compare .
* @ param { Mixed } b The other value to compare .
* @ param { Function } [ callback ] The function to customize comparing values .
* @ param { Function } [ isWhere = false ] A flag to indicate performing partial comparisons .
* @ param { Array } [ stackA = [ ] ] Tracks traversed ` a ` objects .
* @ param { Array } [ stackB = [ ] ] Tracks traversed ` b ` objects .
* @ returns { Boolean } Returns ` true ` if the values are equivalent , else ` false ` .
* /
function baseIsEqual ( a , b , stackA , stackB ) {
if ( a === b ) {
return a !== 0 || ( 1 / a == 1 / b ) ;
}
var type = typeof a ,
otherType = typeof b ;
if ( a === a &&
! ( a && objectTypes [ type ] ) &&
! ( b && objectTypes [ otherType ] ) ) {
return false ;
}
if ( a == null || b == null ) {
return a === b ;
}
var className = toString . call ( a ) ,
otherClass = toString . call ( b ) ;
if ( className != otherClass ) {
return false ;
}
switch ( className ) {
case boolClass :
case dateClass :
return + a == + b ;
case numberClass :
return a != + a
? b != + b
: ( a == 0 ? ( 1 / a == 1 / b ) : a == + b ) ;
case regexpClass :
case stringClass :
return a == String ( b ) ;
}
var isArr = className == arrayClass ;
if ( ! isArr ) {
if ( hasOwnProperty . call ( a , '__wrapped__ ' ) || b instanceof lodash ) {
return baseIsEqual ( a . _ _wrapped _ _ || a , b . _ _wrapped _ _ || b , stackA , stackB ) ;
}
if ( className != objectClass ) {
return false ;
}
var ctorA = a . constructor ,
ctorB = b . constructor ;
if ( ctorA != ctorB && ! (
isFunction ( ctorA ) && ctorA instanceof ctorA &&
isFunction ( ctorB ) && ctorB instanceof ctorB
) ) {
return false ;
}
}
stackA || ( stackA = [ ] ) ;
stackB || ( stackB = [ ] ) ;
var length = stackA . length ;
while ( length -- ) {
if ( stackA [ length ] == a ) {
return stackB [ length ] == b ;
}
}
var result = true ,
size = 0 ;
stackA . push ( a ) ;
stackB . push ( b ) ;
if ( isArr ) {
size = b . length ;
result = size == a . length ;
if ( result ) {
while ( size -- ) {
if ( ! ( result = baseIsEqual ( a [ size ] , b [ size ] , stackA , stackB ) ) ) {
break ;
}
}
}
return result ;
}
forIn ( b , function ( value , key , b ) {
if ( hasOwnProperty . call ( b , key ) ) {
size ++ ;
return ! ( result = hasOwnProperty . call ( a , key ) && baseIsEqual ( a [ key ] , value , stackA , stackB ) ) && indicatorObject ;
}
} ) ;
if ( result ) {
forIn ( a , function ( value , key , a ) {
if ( hasOwnProperty . call ( a , key ) ) {
return ! ( result = -- size > - 1 ) && indicatorObject ;
}
} ) ;
}
return result ;
}
/ * *
* The base implementation of ` _.uniq ` without support for callback shorthands
* or ` thisArg ` binding .
*
* @ private
* @ param { Array } array The array to process .
* @ param { Boolean } [ isSorted = false ] A flag to indicate that ` array ` is sorted .
* @ param { Function } [ callback ] The function called per iteration .
* @ returns { Array } Returns a duplicate - value - free array .
* /
function baseUniq ( array , isSorted , callback ) {
var index = - 1 ,
indexOf = getIndexOf ( ) ,
length = array ? array . length : 0 ,
result = [ ] ,
seen = callback ? [ ] : result ;
while ( ++ index < length ) {
var value = array [ index ] ,
computed = callback ? callback ( value , index , array ) : value ;
if ( isSorted
? ! index || seen [ seen . length - 1 ] !== computed
: indexOf ( seen , computed ) < 0
) {
if ( callback ) {
seen . push ( computed ) ;
}
result . push ( value ) ;
}
}
return result ;
}
/ * *
* Creates a function that aggregates a collection , creating an object composed
* of keys generated from the results of running each element of the collection
* through a callback . The given ` setter ` function sets the keys and values
* of the composed object .
*
* @ private
* @ param { Function } setter The setter function .
* @ returns { Function } Returns the new aggregator function .
* /
function createAggregator ( setter ) {
return function ( collection , callback , thisArg ) {
var result = { } ;
callback = createCallback ( callback , thisArg , 3 ) ;
forEach ( collection , function ( value , key , collection ) {
key = String ( callback ( value , key , collection ) ) ;
setter ( result , value , key , collection ) ;
} ) ;
return result ;
} ;
}
/ * *
* Creates a function that , when called , either curries or invokes ` func `
* with an optional ` this ` binding and partially applied arguments .
*
* @ private
* @ param { Function | String } func The function or method name to reference .
* @ param { Number } bitmask The bitmask of method flags to compose .
* The bitmask may be composed of the following flags :
* 1 - ` _.bind `
* 2 - ` _.bindKey `
* 4 - ` _.curry `
* 8 - ` _.curry ` ( bound )
* 16 - ` _.partial `
* 32 - ` _.partialRight `
* @ param { Array } [ partialArgs ] An array of arguments to prepend to those
* provided to the new function .
* @ param { Array } [ partialRightArgs ] An array of arguments to append to those
* provided to the new function .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` func ` .
* @ param { Number } [ arity ] The arity of ` func ` .
* @ returns { Function } Returns the new bound function .
* /
function createBound ( func , bitmask , partialArgs , partialRightArgs , thisArg , arity ) {
var isBind = bitmask & 1 ,
isBindKey = bitmask & 2 ,
isCurry = bitmask & 4 ,
isCurryBound = bitmask & 8 ,
isPartial = bitmask & 16 ,
isPartialRight = bitmask & 32 ;
if ( ! isBindKey && ! isFunction ( func ) ) {
throw new TypeError ;
}
// use `Function#bind` if it exists and is fast
// (in V8 `Function#bind` is slower except when partially applied)
if ( isBind && ! ( isBindKey || isCurry || isPartialRight ) &&
( support . fastBind || ( nativeBind && partialArgs . length ) ) ) {
var args = [ func , thisArg ] ;
push . apply ( args , partialArgs ) ;
var bound = nativeBind . call . apply ( nativeBind , args ) ;
}
else {
bound = function ( ) {
// `Function#bind` spec
// http://es5.github.io/#x15.3.4.5
var args = arguments ,
thisBinding = isBind ? thisArg : this ;
if ( partialArgs ) {
unshift . apply ( args , partialArgs ) ;
}
if ( partialRightArgs ) {
push . apply ( args , partialRightArgs ) ;
}
if ( isCurry && args . length < arity ) {
bitmask |= 16 & ~ 32
return createBound ( func , ( isCurryBound ? bitmask : bitmask & ~ 3 ) , args , null , thisArg , arity ) ;
}
if ( isBindKey ) {
func = thisBinding [ key ] ;
}
if ( this instanceof bound ) {
// ensure `new bound` is an instance of `func`
thisBinding = createObject ( func . prototype ) ;
// mimic the constructor's `return` behavior
// http://es5.github.io/#x13.2.2
var result = func . apply ( thisBinding , args ) ;
return isObject ( result ) ? result : thisBinding ;
}
return func . apply ( thisBinding , args ) ;
} ;
}
if ( isBindKey ) {
var key = thisArg ;
thisArg = func ;
}
return bound ;
}
/ * *
* Creates a new object with the specified ` prototype ` .
*
* @ private
* @ param { Object } prototype The prototype object .
* @ returns { Object } Returns the new object .
* /
function createObject ( prototype ) {
return isObject ( prototype ) ? nativeCreate ( prototype ) : { } ;
}
// fallback for browsers without `Object.create`
if ( ! nativeCreate ) {
createObject = function ( prototype ) {
if ( isObject ( prototype ) ) {
noop . prototype = prototype ;
var result = new noop ;
noop . prototype = null ;
}
return result || { } ;
} ;
}
/ * *
* Used by ` escape ` to convert characters to HTML entities .
*
* @ private
* @ param { String } match The matched character to escape .
* @ returns { String } Returns the escaped character .
* /
function escapeHtmlChar ( match ) {
return htmlEscapes [ match ] ;
}
/ * *
* Gets the appropriate "indexOf" function . If the ` _.indexOf ` method is
* customized , this method returns the custom method , otherwise it returns
* the ` baseIndexOf ` function .
*
* @ private
* @ returns { Function } Returns the "indexOf" function .
* /
function getIndexOf ( ) {
var result = ( result = lodash . indexOf ) === indexOf ? baseIndexOf : result ;
return result ;
}
/ * *
* Used by ` unescape ` to convert HTML entities to characters .
*
* @ private
* @ param { String } match The matched character to unescape .
* @ returns { String } Returns the unescaped character .
* /
function unescapeHtmlChar ( match ) {
return htmlUnescapes [ match ] ;
}
/*--------------------------------------------------------------------------*/
/ * *
* Checks if ` value ` is an ` arguments ` object .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is an ` arguments ` object , else ` false ` .
* @ example
*
* ( function ( ) { return _ . isArguments ( arguments ) ; } ) ( 1 , 2 , 3 ) ;
* // => true
*
* _ . isArguments ( [ 1 , 2 , 3 ] ) ;
* // => false
* /
function isArguments ( value ) {
return ( value && typeof value == 'object' ) ? toString . call ( value ) == argsClass : false ;
}
// fallback for browsers that can't detect `arguments` objects by [[Class]]
if ( ! isArguments ( arguments ) ) {
isArguments = function ( value ) {
return ( value && typeof value == 'object' ) ? hasOwnProperty . call ( value , 'callee' ) : false ;
} ;
}
/ * *
* Checks if ` value ` is an array .
*
* @ static
* @ memberOf _
* @ type Function
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is an array , else ` false ` .
* @ example
*
* ( function ( ) { return _ . isArray ( arguments ) ; } ) ( ) ;
* // => false
*
* _ . isArray ( [ 1 , 2 , 3 ] ) ;
* // => true
* /
var isArray = nativeIsArray || function ( value ) {
return ( value && typeof value == 'object' ) ? toString . call ( value ) == arrayClass : false ;
} ;
/ * *
* A fallback implementation of ` Object.keys ` which produces an array of the
* given object ' s own enumerable property names .
*
* @ private
* @ type Function
* @ param { Object } object The object to inspect .
* @ returns { Array } Returns an array of property names .
* /
var shimKeys = function ( object ) {
var index , iterable = object , result = [ ] ;
if ( ! iterable ) return result ;
if ( ! ( objectTypes [ typeof object ] ) ) return result ;
for ( index in iterable ) {
if ( hasOwnProperty . call ( iterable , index ) ) {
result . push ( index ) ;
}
}
return result
} ;
/ * *
* Creates an array composed of the own enumerable property names of an object .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Object } object The object to inspect .
* @ returns { Array } Returns an array of property names .
* @ example
*
* _ . keys ( { 'one' : 1 , 'two' : 2 , 'three' : 3 } ) ;
* // => ['one', 'two', 'three'] (order is not guaranteed)
* /
var keys = ! nativeKeys ? shimKeys : function ( object ) {
if ( ! isObject ( object ) ) {
return [ ] ;
}
return nativeKeys ( object ) ;
} ;
/ * *
* Used to convert characters to HTML entities :
*
* Though the ` > ` character is escaped for symmetry , characters like ` > ` and ` / `
* don 't require escaping in HTML and have no special meaning unless they' re part
* of a tag or an unquoted attribute value .
* http : //mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
* /
var htmlEscapes = {
'&' : '&' ,
'<' : '<' ,
'>' : '>' ,
'"' : '"' ,
"'" : ''' ,
'/' : '/'
} ;
/** Used to convert HTML entities to characters */
var htmlUnescapes = invert ( htmlEscapes ) ;
/** Used to match HTML entities and HTML characters */
var reEscapedHtml = RegExp ( '(' + keys ( htmlUnescapes ) . join ( '|' ) + ')' , 'g' ) ,
reUnescapedHtml = RegExp ( '[' + keys ( htmlEscapes ) . join ( '' ) + ']' , 'g' ) ;
/*--------------------------------------------------------------------------*/
/ * *
* Assigns own enumerable properties of source object ( s ) to the destination
* object . Subsequent sources will overwrite property assignments of previous
* sources . If a callback is provided it will be executed to produce the
* assigned values . The callback is bound to ` thisArg ` and invoked with two
* arguments ; ( objectValue , sourceValue ) .
*
* @ static
* @ memberOf _
* @ type Function
* @ alias extend
* @ category Objects
* @ param { Object } object The destination object .
* @ param { Object } [ source1 , source2 , ... ] The source objects .
* @ param { Function } [ callback ] The function to customize assigning values .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Object } Returns the destination object .
* @ example
*
* _ . assign ( { 'name' : 'moe' } , { 'age' : 40 } ) ;
* // => { 'name': 'moe', 'age': 40 }
*
* var defaults = _ . partialRight ( _ . assign , function ( a , b ) {
* return typeof a == 'undefined' ? b : a ;
* } ) ;
*
* var food = { 'name' : 'apple' } ;
* defaults ( food , { 'name' : 'banana' , 'type' : 'fruit' } ) ;
* // => { 'name': 'apple', 'type': 'fruit' }
* /
function assign ( object ) {
if ( ! object ) {
return object ;
}
for ( var argsIndex = 1 , argsLength = arguments . length ; argsIndex < argsLength ; argsIndex ++ ) {
var iterable = arguments [ argsIndex ] ;
if ( iterable ) {
for ( var key in iterable ) {
object [ key ] = iterable [ key ] ;
}
}
}
return object ;
}
/ * *
* Creates a clone of ` value ` . If ` deep ` is ` true ` nested objects will also
* be cloned , otherwise they will be assigned by reference . If a callback
* is provided it will be executed to produce the cloned values . If the
* callback returns ` undefined ` cloning will be handled by the method instead .
* The callback is bound to ` thisArg ` and invoked with one argument ; ( value ) .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to clone .
* @ param { Boolean } [ deep = false ] A flag to indicate a deep clone .
* @ param { Function } [ callback ] The function to customize cloning values .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the cloned ` value ` .
* @ example
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 }
* ] ;
*
* var shallow = _ . clone ( stooges ) ;
* shallow [ 0 ] === stooges [ 0 ] ;
* // => true
*
* var deep = _ . clone ( stooges , true ) ;
* deep [ 0 ] === stooges [ 0 ] ;
* // => false
*
* _ . mixin ( {
* 'clone' : _ . partialRight ( _ . clone , function ( value ) {
* return _ . isElement ( value ) ? value . cloneNode ( false ) : undefined ;
* } )
* } ) ;
*
* var clone = _ . clone ( document . body ) ;
* clone . childNodes . length ;
* // => 0
* /
function clone ( value ) {
return isObject ( value )
? ( isArray ( value ) ? nativeSlice . call ( value ) : assign ( { } , value ) )
: value ;
}
/ * *
* Assigns own enumerable properties of source object ( s ) to the destination
* object for all destination properties that resolve to ` undefined ` . Once a
* property is set , additional defaults of the same property will be ignored .
*
* @ static
* @ memberOf _
* @ type Function
* @ category Objects
* @ param { Object } object The destination object .
* @ param { Object } [ source1 , source2 , ... ] The source objects .
* @ param - { Object } [ guard ] Allows working with ` _.reduce ` without using
* their ` key ` and ` object ` arguments as sources .
* @ returns { Object } Returns the destination object .
* @ example
*
* var food = { 'name' : 'apple' } ;
* _ . defaults ( food , { 'name' : 'banana' , 'type' : 'fruit' } ) ;
* // => { 'name': 'apple', 'type': 'fruit' }
* /
function defaults ( object ) {
if ( ! object ) {
return object ;
}
for ( var argsIndex = 1 , argsLength = arguments . length ; argsIndex < argsLength ; argsIndex ++ ) {
var iterable = arguments [ argsIndex ] ;
if ( iterable ) {
for ( var key in iterable ) {
if ( typeof object [ key ] == 'undefined' ) {
object [ key ] = iterable [ key ] ;
}
}
}
}
return object ;
}
/ * *
* Iterates over own and inherited enumerable properties of an object ,
* executing the callback for each property . The callback is bound to ` thisArg `
* and invoked with three arguments ; ( value , key , object ) . Callbacks may exit
* iteration early by explicitly returning ` false ` .
*
* @ static
* @ memberOf _
* @ type Function
* @ category Objects
* @ param { Object } object The object to iterate over .
* @ param { Function } [ callback = identity ] The function called per iteration .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Object } Returns ` object ` .
* @ example
*
* function Dog ( name ) {
* this . name = name ;
* }
*
* Dog . prototype . bark = function ( ) {
* console . log ( 'Woof, woof!' ) ;
* } ;
*
* _ . forIn ( new Dog ( 'Dagny' ) , function ( value , key ) {
* console . log ( key ) ;
* } ) ;
* // => logs 'bark' and 'name' (order is not guaranteed)
* /
var forIn = function ( collection , callback ) {
var index , iterable = collection , result = iterable ;
if ( ! iterable ) return result ;
if ( ! objectTypes [ typeof iterable ] ) return result ;
for ( index in iterable ) {
if ( callback ( iterable [ index ] , index , collection ) === indicatorObject ) return result ;
}
return result
} ;
/ * *
* Iterates over own enumerable properties of an object , executing the callback
* for each property . The callback is bound to ` thisArg ` and invoked with three
* arguments ; ( value , key , object ) . Callbacks may exit iteration early by
* explicitly returning ` false ` .
*
* @ static
* @ memberOf _
* @ type Function
* @ category Objects
* @ param { Object } object The object to iterate over .
* @ param { Function } [ callback = identity ] The function called per iteration .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Object } Returns ` object ` .
* @ example
*
* _ . forOwn ( { '0' : 'zero' , '1' : 'one' , 'length' : 2 } , function ( num , key ) {
* console . log ( key ) ;
* } ) ;
* // => logs '0', '1', and 'length' (order is not guaranteed)
* /
var forOwn = function ( collection , callback ) {
var index , iterable = collection , result = iterable ;
if ( ! iterable ) return result ;
if ( ! objectTypes [ typeof iterable ] ) return result ;
for ( index in iterable ) {
if ( hasOwnProperty . call ( iterable , index ) ) {
if ( callback ( iterable [ index ] , index , collection ) === indicatorObject ) return result ;
}
}
return result
} ;
/ * *
* Creates a sorted array of property names of all enumerable properties ,
* own and inherited , of ` object ` that have function values .
*
* @ static
* @ memberOf _
* @ alias methods
* @ category Objects
* @ param { Object } object The object to inspect .
* @ returns { Array } Returns an array of property names that have function values .
* @ example
*
* _ . functions ( _ ) ;
* // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
* /
function functions ( object ) {
var result = [ ] ;
forIn ( object , function ( value , key ) {
if ( isFunction ( value ) ) {
result . push ( key ) ;
}
} ) ;
return result . sort ( ) ;
}
/ * *
* Checks if the specified object ` property ` exists and is a direct property ,
* instead of an inherited property .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Object } object The object to check .
* @ param { String } property The property to check for .
* @ returns { Boolean } Returns ` true ` if key is a direct property , else ` false ` .
* @ example
*
* _ . has ( { 'a' : 1 , 'b' : 2 , 'c' : 3 } , 'b' ) ;
* // => true
* /
function has ( object , property ) {
return object ? hasOwnProperty . call ( object , property ) : false ;
}
/ * *
* Creates an object composed of the inverted keys and values of the given object .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Object } object The object to invert .
* @ returns { Object } Returns the created inverted object .
* @ example
*
* _ . invert ( { 'first' : 'moe' , 'second' : 'larry' } ) ;
* // => { 'moe': 'first', 'larry': 'second' }
* /
function invert ( object ) {
var index = - 1 ,
props = keys ( object ) ,
length = props . length ,
result = { } ;
while ( ++ index < length ) {
var key = props [ index ] ;
result [ object [ key ] ] = key ;
}
return result ;
}
/ * *
* Checks if ` value ` is a boolean value .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is a boolean value , else ` false ` .
* @ example
*
* _ . isBoolean ( null ) ;
* // => false
* /
function isBoolean ( value ) {
return value === true || value === false || toString . call ( value ) == boolClass ;
}
/ * *
* Checks if ` value ` is a date .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is a date , else ` false ` .
* @ example
*
* _ . isDate ( new Date ) ;
* // => true
* /
function isDate ( value ) {
return value ? ( typeof value == 'object' && toString . call ( value ) == dateClass ) : false ;
}
/ * *
* Checks if ` value ` is a DOM element .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is a DOM element , else ` false ` .
* @ example
*
* _ . isElement ( document . body ) ;
* // => true
* /
function isElement ( value ) {
return value ? value . nodeType === 1 : false ;
}
/ * *
* Checks if ` value ` is empty . Arrays , strings , or ` arguments ` objects with a
* length of ` 0 ` and objects with no own enumerable properties are considered
* "empty" .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Array | Object | String } value The value to inspect .
* @ returns { Boolean } Returns ` true ` if the ` value ` is empty , else ` false ` .
* @ example
*
* _ . isEmpty ( [ 1 , 2 , 3 ] ) ;
* // => false
*
* _ . isEmpty ( { } ) ;
* // => true
*
* _ . isEmpty ( '' ) ;
* // => true
* /
function isEmpty ( value ) {
if ( ! value ) {
return true ;
}
if ( isArray ( value ) || isString ( value ) ) {
return ! value . length ;
}
for ( var key in value ) {
if ( hasOwnProperty . call ( value , key ) ) {
return false ;
}
}
return true ;
}
/ * *
* Performs a deep comparison between two values to determine if they are
* equivalent to each other . If a callback is provided it will be executed
* to compare values . If the callback returns ` undefined ` comparisons will
* be handled by the method instead . The callback is bound to ` thisArg ` and
* invoked with two arguments ; ( a , b ) .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } a The value to compare .
* @ param { Mixed } b The other value to compare .
* @ param { Function } [ callback ] The function to customize comparing values .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Boolean } Returns ` true ` if the values are equivalent , else ` false ` .
* @ example
*
* var moe = { 'name' : 'moe' , 'age' : 40 } ;
* var copy = { 'name' : 'moe' , 'age' : 40 } ;
*
* moe == copy ;
* // => false
*
* _ . isEqual ( moe , copy ) ;
* // => true
*
* var words = [ 'hello' , 'goodbye' ] ;
* var otherWords = [ 'hi' , 'goodbye' ] ;
*
* _ . isEqual ( words , otherWords , function ( a , b ) {
* var reGreet = /^(?:hello|hi)$/i ,
* aGreet = _ . isString ( a ) && reGreet . test ( a ) ,
* bGreet = _ . isString ( b ) && reGreet . test ( b ) ;
*
* return ( aGreet || bGreet ) ? ( aGreet == bGreet ) : undefined ;
* } ) ;
* // => true
* /
function isEqual ( a , b ) {
return baseIsEqual ( a , b ) ;
}
/ * *
* Checks if ` value ` is , or can be coerced to , a finite number .
*
* Note : This is not the same as native ` isFinite ` which will return true for
* booleans and empty strings . See http : //es5.github.io/#x15.1.2.5.
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is finite , else ` false ` .
* @ example
*
* _ . isFinite ( - 101 ) ;
* // => true
*
* _ . isFinite ( '10' ) ;
* // => true
*
* _ . isFinite ( true ) ;
* // => false
*
* _ . isFinite ( '' ) ;
* // => false
*
* _ . isFinite ( Infinity ) ;
* // => false
* /
function isFinite ( value ) {
return nativeIsFinite ( value ) && ! nativeIsNaN ( parseFloat ( value ) ) ;
}
/ * *
* Checks if ` value ` is a function .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is a function , else ` false ` .
* @ example
*
* _ . isFunction ( _ ) ;
* // => true
* /
function isFunction ( value ) {
return typeof value == 'function' ;
}
// fallback for older versions of Chrome and Safari
if ( isFunction ( /x/ ) ) {
isFunction = function ( value ) {
return typeof value == 'function' && toString . call ( value ) == funcClass ;
} ;
}
/ * *
* Checks if ` value ` is the language type of Object .
* ( e . g . arrays , functions , objects , regexes , ` new Number(0) ` , and ` new String('') ` )
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is an object , else ` false ` .
* @ example
*
* _ . isObject ( { } ) ;
* // => true
*
* _ . isObject ( [ 1 , 2 , 3 ] ) ;
* // => true
*
* _ . isObject ( 1 ) ;
* // => false
* /
function isObject ( value ) {
// check if the value is the ECMAScript language type of Object
// http://es5.github.io/#x8
// and avoid a V8 bug
// http://code.google.com/p/v8/issues/detail?id=2291
return ! ! ( value && objectTypes [ typeof value ] ) ;
}
/ * *
* Checks if ` value ` is ` NaN ` .
*
* Note : This is not the same as native ` isNaN ` which will return ` true ` for
* ` undefined ` and other non - numeric values . See http : //es5.github.io/#x15.1.2.4.
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is ` NaN ` , else ` false ` .
* @ example
*
* _ . isNaN ( NaN ) ;
* // => true
*
* _ . isNaN ( new Number ( NaN ) ) ;
* // => true
*
* isNaN ( undefined ) ;
* // => true
*
* _ . isNaN ( undefined ) ;
* // => false
* /
function isNaN ( value ) {
// `NaN` as a primitive is the only value that is not equal to itself
// (perform the [[Class]] check first to avoid errors with some host objects in IE)
return isNumber ( value ) && value != + value ;
}
/ * *
* Checks if ` value ` is ` null ` .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is ` null ` , else ` false ` .
* @ example
*
* _ . isNull ( null ) ;
* // => true
*
* _ . isNull ( undefined ) ;
* // => false
* /
function isNull ( value ) {
return value === null ;
}
/ * *
* Checks if ` value ` is a number .
*
* Note : ` NaN ` is considered a number . See http : //es5.github.io/#x8.5.
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is a number , else ` false ` .
* @ example
*
* _ . isNumber ( 8.4 * 5 ) ;
* // => true
* /
function isNumber ( value ) {
return typeof value == 'number' || toString . call ( value ) == numberClass ;
}
/ * *
* Checks if ` value ` is a regular expression .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is a regular expression , else ` false ` .
* @ example
*
* _ . isRegExp ( /moe/ ) ;
* // => true
* /
function isRegExp ( value ) {
return ( value && objectTypes [ typeof value ] ) ? toString . call ( value ) == regexpClass : false ;
}
/ * *
* Checks if ` value ` is a string .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is a string , else ` false ` .
* @ example
*
* _ . isString ( 'moe' ) ;
* // => true
* /
function isString ( value ) {
return typeof value == 'string' || toString . call ( value ) == stringClass ;
}
/ * *
* Checks if ` value ` is ` undefined ` .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Mixed } value The value to check .
* @ returns { Boolean } Returns ` true ` if the ` value ` is ` undefined ` , else ` false ` .
* @ example
*
* _ . isUndefined ( void 0 ) ;
* // => true
* /
function isUndefined ( value ) {
return typeof value == 'undefined' ;
}
/ * *
* Creates a shallow clone of ` object ` excluding the specified properties .
* Property names may be specified as individual arguments or as arrays of
* property names . If a callback is provided it will be executed for each
* property of ` object ` omitting the properties the callback returns truthy
* for . The callback is bound to ` thisArg ` and invoked with three arguments ;
* ( value , key , object ) .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Object } object The source object .
* @ param { Function | String } callback | [ prop1 , prop2 , ... ] The properties to omit
* or the function called per iteration .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Object } Returns an object without the omitted properties .
* @ example
*
* _ . omit ( { 'name' : 'moe' , 'age' : 40 } , 'age' ) ;
* // => { 'name': 'moe' }
*
* _ . omit ( { 'name' : 'moe' , 'age' : 40 } , function ( value ) {
* return typeof value == 'number' ;
* } ) ;
* // => { 'name': 'moe' }
* /
function omit ( object ) {
var indexOf = getIndexOf ( ) ,
props = baseFlatten ( arguments , true , false , 1 ) ,
result = { } ;
forIn ( object , function ( value , key ) {
if ( indexOf ( props , key ) < 0 ) {
result [ key ] = value ;
}
} ) ;
return result ;
}
/ * *
* Creates a two dimensional array of an object ' s key - value pairs ,
* i . e . ` [[key1, value1], [key2, value2]] ` .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Object } object The object to inspect .
* @ returns { Array } Returns new array of key - value pairs .
* @ example
*
* _ . pairs ( { 'moe' : 30 , 'larry' : 40 } ) ;
* // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
* /
function pairs ( object ) {
var index = - 1 ,
props = keys ( object ) ,
length = props . length ,
result = Array ( length ) ;
while ( ++ index < length ) {
var key = props [ index ] ;
result [ index ] = [ key , object [ key ] ] ;
}
return result ;
}
/ * *
* Creates a shallow clone of ` object ` composed of the specified properties .
* Property names may be specified as individual arguments or as arrays of
* property names . If a callback is provided it will be executed for each
* property of ` object ` picking the properties the callback returns truthy
* for . The callback is bound to ` thisArg ` and invoked with three arguments ;
* ( value , key , object ) .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Object } object The source object .
* @ param { Array | Function | String } callback | [ prop1 , prop2 , ... ] The function
* called per iteration or property names to pick , specified as individual
* property names or arrays of property names .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Object } Returns an object composed of the picked properties .
* @ example
*
* _ . pick ( { 'name' : 'moe' , '_userid' : 'moe1' } , 'name' ) ;
* // => { 'name': 'moe' }
*
* _ . pick ( { 'name' : 'moe' , '_userid' : 'moe1' } , function ( value , key ) {
* return key . charAt ( 0 ) != '_' ;
* } ) ;
* // => { 'name': 'moe' }
* /
function pick ( object ) {
var index = - 1 ,
props = baseFlatten ( arguments , true , false , 1 ) ,
length = props . length ,
result = { } ;
while ( ++ index < length ) {
var prop = props [ index ] ;
if ( prop in object ) {
result [ prop ] = object [ prop ] ;
}
}
return result ;
}
/ * *
* Creates an array composed of the own enumerable property values of ` object ` .
*
* @ static
* @ memberOf _
* @ category Objects
* @ param { Object } object The object to inspect .
* @ returns { Array } Returns an array of property values .
* @ example
*
* _ . values ( { 'one' : 1 , 'two' : 2 , 'three' : 3 } ) ;
* // => [1, 2, 3] (order is not guaranteed)
* /
function values ( object ) {
var index = - 1 ,
props = keys ( object ) ,
length = props . length ,
result = Array ( length ) ;
while ( ++ index < length ) {
result [ index ] = object [ props [ index ] ] ;
}
return result ;
}
/*--------------------------------------------------------------------------*/
/ * *
* Checks if a given value is present in a collection using strict equality
* for comparisons , i . e . ` === ` . If ` fromIndex ` is negative , it is used as the
* offset from the end of the collection .
*
* @ static
* @ memberOf _
* @ alias include
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Mixed } target The value to check for .
* @ param { Number } [ fromIndex = 0 ] The index to search from .
* @ returns { Boolean } Returns ` true ` if the ` target ` element is found , else ` false ` .
* @ example
*
* _ . contains ( [ 1 , 2 , 3 ] , 1 ) ;
* // => true
*
* _ . contains ( [ 1 , 2 , 3 ] , 1 , 2 ) ;
* // => false
*
* _ . contains ( { 'name' : 'moe' , 'age' : 40 } , 'moe' ) ;
* // => true
*
* _ . contains ( 'curly' , 'ur' ) ;
* // => true
* /
function contains ( collection , target ) {
var indexOf = getIndexOf ( ) ,
length = collection ? collection . length : 0 ,
result = false ;
if ( length && typeof length == 'number' ) {
result = indexOf ( collection , target ) > - 1 ;
} else {
forOwn ( collection , function ( value ) {
return ( result = value === target ) && indicatorObject ;
} ) ;
}
return result ;
}
/ * *
* Creates an object composed of keys generated from the results of running
* each element of ` collection ` through the callback . The corresponding value
* of each key is the number of times the key was returned by the callback .
* The callback is bound to ` thisArg ` and invoked with three arguments ;
* ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Object } Returns the composed aggregate object .
* @ example
*
* _ . countBy ( [ 4.3 , 6.1 , 6.4 ] , function ( num ) { return Math . floor ( num ) ; } ) ;
* // => { '4': 1, '6': 2 }
*
* _ . countBy ( [ 4.3 , 6.1 , 6.4 ] , function ( num ) { return this . floor ( num ) ; } , Math ) ;
* // => { '4': 1, '6': 2 }
*
* _ . countBy ( [ 'one' , 'two' , 'three' ] , 'length' ) ;
* // => { '3': 2, '5': 1 }
* /
var countBy = createAggregator ( function ( result , value , key ) {
( hasOwnProperty . call ( result , key ) ? result [ key ] ++ : result [ key ] = 1 ) ;
} ) ;
/ * *
* Checks if the given callback returns truthy value for * * all * * elements of
* a collection . The callback is bound to ` thisArg ` and invoked with three
* arguments ; ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias all
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Boolean } Returns ` true ` if all elements passed the callback check ,
* else ` false ` .
* @ example
*
* _ . every ( [ true , 1 , null , 'yes' ] , Boolean ) ;
* // => false
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . every ( stooges , 'age' ) ;
* // => true
*
* // using "_.where" callback shorthand
* _ . every ( stooges , { 'age' : 50 } ) ;
* // => false
* /
function every ( collection , callback , thisArg ) {
var result = true ;
callback = createCallback ( callback , thisArg , 3 ) ;
var index = - 1 ,
length = collection ? collection . length : 0 ;
if ( typeof length == 'number' ) {
while ( ++ index < length ) {
if ( ! ( result = ! ! callback ( collection [ index ] , index , collection ) ) ) {
break ;
}
}
} else {
forOwn ( collection , function ( value , index , collection ) {
return ! ( result = ! ! callback ( value , index , collection ) ) && indicatorObject ;
} ) ;
}
return result ;
}
/ * *
* Iterates over elements of a collection , returning an array of all elements
* the callback returns truthy for . The callback is bound to ` thisArg ` and
* invoked with three arguments ; ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias select
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a new array of elements that passed the callback check .
* @ example
*
* var evens = _ . filter ( [ 1 , 2 , 3 , 4 , 5 , 6 ] , function ( num ) { return num % 2 == 0 ; } ) ;
* // => [2, 4, 6]
*
* var food = [
* { 'name' : 'apple' , 'organic' : false , 'type' : 'fruit' } ,
* { 'name' : 'carrot' , 'organic' : true , 'type' : 'vegetable' }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . filter ( food , 'organic' ) ;
* // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
*
* // using "_.where" callback shorthand
* _ . filter ( food , { 'type' : 'fruit' } ) ;
* // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
* /
function filter ( collection , callback , thisArg ) {
var result = [ ] ;
callback = createCallback ( callback , thisArg , 3 ) ;
var index = - 1 ,
length = collection ? collection . length : 0 ;
if ( typeof length == 'number' ) {
while ( ++ index < length ) {
var value = collection [ index ] ;
if ( callback ( value , index , collection ) ) {
result . push ( value ) ;
}
}
} else {
forOwn ( collection , function ( value , index , collection ) {
if ( callback ( value , index , collection ) ) {
result . push ( value ) ;
}
} ) ;
}
return result ;
}
/ * *
* Iterates over elements of a collection , returning the first element that
* the callback returns truthy for . The callback is bound to ` thisArg ` and
* invoked with three arguments ; ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias detect , findWhere
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the found element , else ` undefined ` .
* @ example
*
* _ . find ( [ 1 , 2 , 3 , 4 ] , function ( num ) {
* return num % 2 == 0 ;
* } ) ;
* // => 2
*
* var food = [
* { 'name' : 'apple' , 'organic' : false , 'type' : 'fruit' } ,
* { 'name' : 'banana' , 'organic' : true , 'type' : 'fruit' } ,
* { 'name' : 'beet' , 'organic' : false , 'type' : 'vegetable' }
* ] ;
*
* // using "_.where" callback shorthand
* _ . find ( food , { 'type' : 'vegetable' } ) ;
* // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
*
* // using "_.pluck" callback shorthand
* _ . find ( food , 'organic' ) ;
* // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
* /
function find ( collection , callback , thisArg ) {
callback = createCallback ( callback , thisArg , 3 ) ;
var index = - 1 ,
length = collection ? collection . length : 0 ;
if ( typeof length == 'number' ) {
while ( ++ index < length ) {
var value = collection [ index ] ;
if ( callback ( value , index , collection ) ) {
return value ;
}
}
} else {
var result ;
forOwn ( collection , function ( value , index , collection ) {
if ( callback ( value , index , collection ) ) {
result = value ;
return indicatorObject ;
}
} ) ;
return result ;
}
}
/ * *
* Examines each element in a ` collection ` , returning the first that
* has the given ` properties ` . When checking ` properties ` , this method
* performs a deep comparison between values to determine if they are
* equivalent to each other .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Object } properties The object of property values to filter by .
* @ returns { Mixed } Returns the found element , else ` undefined ` .
* @ example
*
* var food = [
* { 'name' : 'apple' , 'organic' : false , 'type' : 'fruit' } ,
* { 'name' : 'banana' , 'organic' : true , 'type' : 'fruit' } ,
* { 'name' : 'beet' , 'organic' : false , 'type' : 'vegetable' }
* ] ;
*
* _ . findWhere ( food , { 'type' : 'vegetable' } ) ;
* // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
* /
function findWhere ( object , properties ) {
return where ( object , properties , true ) ;
}
/ * *
* Iterates over elements of a collection , executing the callback for each
* element . The callback is bound to ` thisArg ` and invoked with three arguments ;
* ( value , index | key , collection ) . Callbacks may exit iteration early by
* explicitly returning ` false ` .
*
* @ static
* @ memberOf _
* @ alias each
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function } [ callback = identity ] The function called per iteration .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array | Object | String } Returns ` collection ` .
* @ example
*
* _ ( [ 1 , 2 , 3 ] ) . forEach ( function ( num ) { console . log ( num ) ; } ) . join ( ',' ) ;
* // => logs each number and returns '1,2,3'
*
* _ . forEach ( { 'one' : 1 , 'two' : 2 , 'three' : 3 } , function ( num ) { console . log ( num ) ; } ) ;
* // => logs each number value and returns the object (order is not guaranteed)
* /
function forEach ( collection , callback , thisArg ) {
var index = - 1 ,
length = collection ? collection . length : 0 ;
callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback ( callback , thisArg , 3 ) ;
if ( typeof length == 'number' ) {
while ( ++ index < length ) {
if ( callback ( collection [ index ] , index , collection ) === indicatorObject ) {
break ;
}
}
} else {
forOwn ( collection , callback ) ;
}
}
/ * *
* This method is like ` _.forEach ` except that it iterates over elements
* of a ` collection ` from right to left .
*
* @ static
* @ memberOf _
* @ alias eachRight
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function } [ callback = identity ] The function called per iteration .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array | Object | String } Returns ` collection ` .
* @ example
*
* _ ( [ 1 , 2 , 3 ] ) . forEachRight ( function ( num ) { console . log ( num ) ; } ) . join ( ',' ) ;
* // => logs each number from right to left and returns '3,2,1'
* /
function forEachRight ( collection , callback ) {
var iterable = collection ,
length = collection ? collection . length : 0 ;
if ( typeof length != 'number' ) {
var props = keys ( collection ) ;
length = props . length ;
}
forEach ( collection , function ( value , index , collection ) {
index = props ? props [ -- length ] : -- length ;
return callback ( iterable [ index ] , index , collection ) === false && indicatorObject ;
} ) ;
}
/ * *
* Creates an object composed of keys generated from the results of running
* each element of a collection through the callback . The corresponding value
* of each key is an array of the elements responsible for generating the key .
* The callback is bound to ` thisArg ` and invoked with three arguments ;
* ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false `
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Object } Returns the composed aggregate object .
* @ example
*
* _ . groupBy ( [ 4.2 , 6.1 , 6.4 ] , function ( num ) { return Math . floor ( num ) ; } ) ;
* // => { '4': [4.2], '6': [6.1, 6.4] }
*
* _ . groupBy ( [ 4.2 , 6.1 , 6.4 ] , function ( num ) { return this . floor ( num ) ; } , Math ) ;
* // => { '4': [4.2], '6': [6.1, 6.4] }
*
* // using "_.pluck" callback shorthand
* _ . groupBy ( [ 'one' , 'two' , 'three' ] , 'length' ) ;
* // => { '3': ['one', 'two'], '5': ['three'] }
* /
var groupBy = createAggregator ( function ( result , value , key ) {
( hasOwnProperty . call ( result , key ) ? result [ key ] : result [ key ] = [ ] ) . push ( value ) ;
} ) ;
/ * *
* Invokes the method named by ` methodName ` on each element in the ` collection `
* returning an array of the results of each invoked method . Additional arguments
* will be provided to each invoked method . If ` methodName ` is a function it
* will be invoked for , and ` this ` bound to , each element in the ` collection ` .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | String } methodName The name of the method to invoke or
* the function invoked per iteration .
* @ param { Mixed } [ arg1 , arg2 , ... ] Arguments to invoke the method with .
* @ returns { Array } Returns a new array of the results of each invoked method .
* @ example
*
* _ . invoke ( [ [ 5 , 1 , 7 ] , [ 3 , 2 , 1 ] ] , 'sort' ) ;
* // => [[1, 5, 7], [1, 2, 3]]
*
* _ . invoke ( [ 123 , 456 ] , String . prototype . split , '' ) ;
* // => [['1', '2', '3'], ['4', '5', '6']]
* /
function invoke ( collection , methodName ) {
var args = nativeSlice . call ( arguments , 2 ) ,
index = - 1 ,
isFunc = typeof methodName == 'function' ,
length = collection ? collection . length : 0 ,
result = Array ( typeof length == 'number' ? length : 0 ) ;
forEach ( collection , function ( value ) {
result [ ++ index ] = ( isFunc ? methodName : value [ methodName ] ) . apply ( value , args ) ;
} ) ;
return result ;
}
/ * *
* Creates an array of values by running each element in the collection
* through the callback . The callback is bound to ` thisArg ` and invoked with
* three arguments ; ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias collect
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a new array of the results of each ` callback ` execution .
* @ example
*
* _ . map ( [ 1 , 2 , 3 ] , function ( num ) { return num * 3 ; } ) ;
* // => [3, 6, 9]
*
* _ . map ( { 'one' : 1 , 'two' : 2 , 'three' : 3 } , function ( num ) { return num * 3 ; } ) ;
* // => [3, 6, 9] (order is not guaranteed)
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . map ( stooges , 'name' ) ;
* // => ['moe', 'larry']
* /
function map ( collection , callback , thisArg ) {
var index = - 1 ,
length = collection ? collection . length : 0 ;
callback = createCallback ( callback , thisArg , 3 ) ;
if ( typeof length == 'number' ) {
var result = Array ( length ) ;
while ( ++ index < length ) {
result [ index ] = callback ( collection [ index ] , index , collection ) ;
}
} else {
result = [ ] ;
forOwn ( collection , function ( value , key , collection ) {
result [ ++ index ] = callback ( value , key , collection ) ;
} ) ;
}
return result ;
}
/ * *
* Retrieves the maximum value of an array . If a callback is provided it
* will be executed for each value in the array to generate the criterion by
* which the value is ranked . The callback is bound to ` thisArg ` and invoked
* with three arguments ; ( value , index , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the maximum value .
* @ example
*
* _ . max ( [ 4 , 2 , 8 , 6 ] ) ;
* // => 8
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 }
* ] ;
*
* _ . max ( stooges , function ( stooge ) { return stooge . age ; } ) ;
* // => { 'name': 'larry', 'age': 50 };
*
* // using "_.pluck" callback shorthand
* _ . max ( stooges , 'age' ) ;
* // => { 'name': 'larry', 'age': 50 };
* /
function max ( collection , callback , thisArg ) {
var computed = - Infinity ,
result = computed ;
var index = - 1 ,
length = collection ? collection . length : 0 ;
if ( ! callback && typeof length == 'number' ) {
while ( ++ index < length ) {
var value = collection [ index ] ;
if ( value > result ) {
result = value ;
}
}
} else {
callback = createCallback ( callback , thisArg , 3 ) ;
forEach ( collection , function ( value , index , collection ) {
var current = callback ( value , index , collection ) ;
if ( current > computed ) {
computed = current ;
result = value ;
}
} ) ;
}
return result ;
}
/ * *
* Retrieves the minimum value of an array . If a callback is provided it
* will be executed for each value in the array to generate the criterion by
* which the value is ranked . The callback is bound to ` thisArg ` and invoked
* with three arguments ; ( value , index , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the minimum value .
* @ example
*
* _ . min ( [ 4 , 2 , 8 , 6 ] ) ;
* // => 2
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 }
* ] ;
*
* _ . min ( stooges , function ( stooge ) { return stooge . age ; } ) ;
* // => { 'name': 'moe', 'age': 40 };
*
* // using "_.pluck" callback shorthand
* _ . min ( stooges , 'age' ) ;
* // => { 'name': 'moe', 'age': 40 };
* /
function min ( collection , callback , thisArg ) {
var computed = Infinity ,
result = computed ;
var index = - 1 ,
length = collection ? collection . length : 0 ;
if ( ! callback && typeof length == 'number' ) {
while ( ++ index < length ) {
var value = collection [ index ] ;
if ( value < result ) {
result = value ;
}
}
} else {
callback = createCallback ( callback , thisArg , 3 ) ;
forEach ( collection , function ( value , index , collection ) {
var current = callback ( value , index , collection ) ;
if ( current < computed ) {
computed = current ;
result = value ;
}
} ) ;
}
return result ;
}
/ * *
* Retrieves the value of a specified property from all elements in the ` collection ` .
*
* @ static
* @ memberOf _
* @ type Function
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { String } property The property to pluck .
* @ returns { Array } Returns a new array of property values .
* @ example
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 }
* ] ;
*
* _ . pluck ( stooges , 'name' ) ;
* // => ['moe', 'larry']
* /
function pluck ( collection , property ) {
var index = - 1 ,
length = collection ? collection . length : 0 ;
if ( typeof length == 'number' ) {
var result = Array ( length ) ;
while ( ++ index < length ) {
result [ index ] = collection [ index ] [ property ] ;
}
}
return result || map ( collection , property ) ;
}
/ * *
* Reduces a collection to a value which is the accumulated result of running
* each element in the collection through the callback , where each successive
* callback execution consumes the return value of the previous execution . If
* ` accumulator ` is not provided the first element of the collection will be
* used as the initial ` accumulator ` value . The callback is bound to ` thisArg `
* and invoked with four arguments ; ( accumulator , value , index | key , collection ) .
*
* @ static
* @ memberOf _
* @ alias foldl , inject
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function } [ callback = identity ] The function called per iteration .
* @ param { Mixed } [ accumulator ] Initial value of the accumulator .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the accumulated value .
* @ example
*
* var sum = _ . reduce ( [ 1 , 2 , 3 ] , function ( sum , num ) {
* return sum + num ;
* } ) ;
* // => 6
*
* var mapped = _ . reduce ( { 'a' : 1 , 'b' : 2 , 'c' : 3 } , function ( result , num , key ) {
* result [ key ] = num * 3 ;
* return result ;
* } , { } ) ;
* // => { 'a': 3, 'b': 6, 'c': 9 }
* /
function reduce ( collection , callback , accumulator , thisArg ) {
if ( ! collection ) return accumulator ;
var noaccum = arguments . length < 3 ;
callback = baseCreateCallback ( callback , thisArg , 4 ) ;
var index = - 1 ,
length = collection . length ;
if ( typeof length == 'number' ) {
if ( noaccum ) {
accumulator = collection [ ++ index ] ;
}
while ( ++ index < length ) {
accumulator = callback ( accumulator , collection [ index ] , index , collection ) ;
}
} else {
forOwn ( collection , function ( value , index , collection ) {
accumulator = noaccum
? ( noaccum = false , value )
: callback ( accumulator , value , index , collection )
} ) ;
}
return accumulator ;
}
/ * *
* This method is like ` _.reduce ` except that it iterates over elements
* of a ` collection ` from right to left .
*
* @ static
* @ memberOf _
* @ alias foldr
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function } [ callback = identity ] The function called per iteration .
* @ param { Mixed } [ accumulator ] Initial value of the accumulator .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the accumulated value .
* @ example
*
* 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]
* /
function reduceRight ( collection , callback , accumulator , thisArg ) {
var noaccum = arguments . length < 3 ;
callback = baseCreateCallback ( callback , thisArg , 4 ) ;
forEachRight ( collection , function ( value , index , collection ) {
accumulator = noaccum
? ( noaccum = false , value )
: callback ( accumulator , value , index , collection ) ;
} ) ;
return accumulator ;
}
/ * *
* The opposite of ` _.filter ` this method returns the elements of a
* collection that the callback does * * not * * return truthy for .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a new array of elements that failed the callback check .
* @ example
*
* var odds = _ . reject ( [ 1 , 2 , 3 , 4 , 5 , 6 ] , function ( num ) { return num % 2 == 0 ; } ) ;
* // => [1, 3, 5]
*
* var food = [
* { 'name' : 'apple' , 'organic' : false , 'type' : 'fruit' } ,
* { 'name' : 'carrot' , 'organic' : true , 'type' : 'vegetable' }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . reject ( food , 'organic' ) ;
* // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
*
* // using "_.where" callback shorthand
* _ . reject ( food , { 'type' : 'fruit' } ) ;
* // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
* /
function reject ( collection , callback , thisArg ) {
callback = createCallback ( callback , thisArg , 3 ) ;
return filter ( collection , function ( value , index , collection ) {
return ! callback ( value , index , collection ) ;
} ) ;
}
/ * *
* Creates an array of shuffled values , using a version of the Fisher - Yates
* shuffle . See http : //en.wikipedia.org/wiki/Fisher-Yates_shuffle.
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to shuffle .
* @ returns { Array } Returns a new shuffled collection .
* @ example
*
* _ . shuffle ( [ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
* // => [4, 1, 6, 3, 5, 2]
* /
function shuffle ( collection ) {
var index = - 1 ,
length = collection ? collection . length : 0 ,
result = Array ( typeof length == 'number' ? length : 0 ) ;
forEach ( collection , function ( value ) {
var rand = floor ( nativeRandom ( ) * ( ++ index + 1 ) ) ;
result [ index ] = result [ rand ] ;
result [ rand ] = value ;
} ) ;
return result ;
}
/ * *
* Gets the size of the ` collection ` by returning ` collection.length ` for arrays
* and array - like objects or the number of own enumerable properties for objects .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to inspect .
* @ returns { Number } Returns ` collection.length ` or number of own enumerable properties .
* @ example
*
* _ . size ( [ 1 , 2 ] ) ;
* // => 2
*
* _ . size ( { 'one' : 1 , 'two' : 2 , 'three' : 3 } ) ;
* // => 3
*
* _ . size ( 'curly' ) ;
* // => 5
* /
function size ( collection ) {
var length = collection ? collection . length : 0 ;
return typeof length == 'number' ? length : keys ( collection ) . length ;
}
/ * *
* Checks if the callback returns a truthy value for * * any * * element of a
* collection . The function returns as soon as it finds a passing value and
* does not iterate over the entire collection . The callback is bound to
* ` thisArg ` and invoked with three arguments ; ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias any
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Boolean } Returns ` true ` if any element passed the callback check ,
* else ` false ` .
* @ example
*
* _ . some ( [ null , 0 , 'yes' , false ] , Boolean ) ;
* // => true
*
* var food = [
* { 'name' : 'apple' , 'organic' : false , 'type' : 'fruit' } ,
* { 'name' : 'carrot' , 'organic' : true , 'type' : 'vegetable' }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . some ( food , 'organic' ) ;
* // => true
*
* // using "_.where" callback shorthand
* _ . some ( food , { 'type' : 'meat' } ) ;
* // => false
* /
function some ( collection , callback , thisArg ) {
var result ;
callback = createCallback ( callback , thisArg , 3 ) ;
var index = - 1 ,
length = collection ? collection . length : 0 ;
if ( typeof length == 'number' ) {
while ( ++ index < length ) {
if ( ( result = callback ( collection [ index ] , index , collection ) ) ) {
break ;
}
}
} else {
forOwn ( collection , function ( value , index , collection ) {
return ( result = callback ( value , index , collection ) ) && indicatorObject ;
} ) ;
}
return ! ! result ;
}
/ * *
* Creates an array of elements , sorted in ascending order by the results of
* running each element in a collection through the callback . This method
* performs a stable sort , that is , it will preserve the original sort order
* of equal elements . The callback is bound to ` thisArg ` and invoked with
* three arguments ; ( value , index | key , collection ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a new array of sorted elements .
* @ example
*
* _ . sortBy ( [ 1 , 2 , 3 ] , function ( num ) { return Math . sin ( num ) ; } ) ;
* // => [3, 1, 2]
*
* _ . sortBy ( [ 1 , 2 , 3 ] , function ( num ) { return this . sin ( num ) ; } , Math ) ;
* // => [3, 1, 2]
*
* // using "_.pluck" callback shorthand
* _ . sortBy ( [ 'banana' , 'strawberry' , 'apple' ] , 'length' ) ;
* // => ['apple', 'banana', 'strawberry']
* /
function sortBy ( collection , callback , thisArg ) {
var index = - 1 ,
length = collection ? collection . length : 0 ,
result = Array ( typeof length == 'number' ? length : 0 ) ;
callback = createCallback ( callback , thisArg , 3 ) ;
forEach ( collection , function ( value , key , collection ) {
result [ ++ index ] = {
'criteria' : callback ( value , key , collection ) ,
'index' : index ,
'value' : value
} ;
} ) ;
length = result . length ;
result . sort ( compareAscending ) ;
while ( length -- ) {
result [ length ] = result [ length ] . value ;
}
return result ;
}
/ * *
* Converts the ` collection ` to an array .
*
* @ static
* @ memberOf _
* @ category Collections
* @ param { Array | Object | String } collection The collection to convert .
* @ returns { Array } Returns the new converted array .
* @ example
*
* ( function ( ) { return _ . toArray ( arguments ) . slice ( 1 ) ; } ) ( 1 , 2 , 3 , 4 ) ;
* // => [2, 3, 4]
* /
function toArray ( collection ) {
if ( isArray ( collection ) ) {
return nativeSlice . call ( collection ) ;
}
if ( collection && typeof collection . length == 'number' ) {
return map ( collection ) ;
}
return values ( collection ) ;
}
/ * *
* Performs a deep comparison of each element in a ` collection ` to the given
* ` properties ` object , returning an array of all elements that have equivalent
* property values .
*
* @ static
* @ memberOf _
* @ type Function
* @ category Collections
* @ param { Array | Object | String } collection The collection to iterate over .
* @ param { Object } properties The object of property values to filter by .
* @ returns { Array } Returns a new array of elements that have the given ` properties ` .
* @ example
*
* var stooges = [
* { 'name' : 'curly' , 'age' : 30 , 'quotes' : [ 'Oh, a wise guy, eh?' , 'Poifect!' ] } ,
* { 'name' : 'moe' , 'age' : '40' , 'quotes' : [ 'Spread out!' , 'You knucklehead!' ] }
* ] ;
*
* _ . where ( stooges , { 'age' : 40 } ) ;
* // => [{ 'name': 'moe', 'age': '40', 'quotes': ['Spread out!', 'You knucklehead!'] }]
*
* _ . where ( stooges , { 'quotes' : [ 'Poifect!' ] } ) ;
* // => [{ 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }]
* /
function where ( collection , properties , first ) {
return ( first && isEmpty ( properties ) )
? undefined
: ( first ? find : filter ) ( collection , properties ) ;
}
/*--------------------------------------------------------------------------*/
/ * *
* Creates an array with all falsey values removed . The values ` false ` , ` null ` ,
* ` 0 ` , ` "" ` , ` undefined ` , and ` NaN ` are all falsey .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to compact .
* @ returns { Array } Returns a new array of filtered values .
* @ example
*
* _ . compact ( [ 0 , 1 , false , 2 , '' , 3 ] ) ;
* // => [1, 2, 3]
* /
function compact ( array ) {
var index = - 1 ,
length = array ? array . length : 0 ,
result = [ ] ;
while ( ++ index < length ) {
var value = array [ index ] ;
if ( value ) {
result . push ( value ) ;
}
}
return result ;
}
/ * *
* Creates an array excluding all values of the provided arrays using strict
* equality for comparisons , i . e . ` === ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to process .
* @ param { Array } [ array1 , array2 , ... ] The arrays of values to exclude .
* @ returns { Array } Returns a new array of filtered values .
* @ example
*
* _ . difference ( [ 1 , 2 , 3 , 4 , 5 ] , [ 5 , 2 , 10 ] ) ;
* // => [1, 3, 4]
* /
function difference ( array ) {
var index = - 1 ,
indexOf = getIndexOf ( ) ,
length = array . length ,
flattened = baseFlatten ( arguments , true , true , 1 ) ,
result = [ ] ;
while ( ++ index < length ) {
var value = array [ index ] ;
if ( indexOf ( flattened , value ) < 0 ) {
result . push ( value ) ;
}
}
return result ;
}
/ * *
* Gets the first element of an array . If a number ` n ` is provided the first
* ` n ` elements of the array are returned . If a callback is provided elements
* at the beginning of the array are returned as long as the callback returns
* truthy . The callback is bound to ` thisArg ` and invoked with three arguments ;
* ( value , index , array ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias head , take
* @ category Arrays
* @ param { Array } array The array to query .
* @ param { Function | Object | Number | String } [ callback | n ] The function called
* per element or the number of elements to return . If a property name or
* object is provided it will be used to create a "_.pluck" or "_.where"
* style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the first element ( s ) of ` array ` .
* @ example
*
* _ . first ( [ 1 , 2 , 3 ] ) ;
* // => 1
*
* _ . first ( [ 1 , 2 , 3 ] , 2 ) ;
* // => [1, 2]
*
* _ . first ( [ 1 , 2 , 3 ] , function ( num ) {
* return num < 3 ;
* } ) ;
* // => [1, 2]
*
* var food = [
* { 'name' : 'banana' , 'organic' : true } ,
* { 'name' : 'beet' , 'organic' : false } ,
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . first ( food , 'organic' ) ;
* // => [{ 'name': 'banana', 'organic': true }]
*
* var food = [
* { 'name' : 'apple' , 'type' : 'fruit' } ,
* { 'name' : 'banana' , 'type' : 'fruit' } ,
* { 'name' : 'beet' , 'type' : 'vegetable' }
* ] ;
*
* // using "_.where" callback shorthand
* _ . first ( food , { 'type' : 'fruit' } ) ;
* // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
* /
function first ( array , callback , thisArg ) {
if ( array ) {
var n = 0 ,
length = array . length ;
if ( typeof callback != 'number' && callback != null ) {
var index = - 1 ;
callback = createCallback ( callback , thisArg , 3 ) ;
while ( ++ index < length && callback ( array [ index ] , index , array ) ) {
n ++ ;
}
} else {
n = callback ;
if ( n == null || thisArg ) {
return array [ 0 ] ;
}
}
return nativeSlice . call ( array , 0 , nativeMin ( nativeMax ( 0 , n ) , length ) ) ;
}
}
/ * *
* Flattens a nested array ( the nesting can be to any depth ) . If ` isShallow `
* is truthy , the array will only be flattened a single level . If a callback
* is provided each element of the array is passed through the callback before
* flattening . The callback is bound to ` thisArg ` and invoked with three
* arguments ; ( value , index , array ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to flatten .
* @ param { Boolean } [ isShallow = false ] A flag to restrict flattening to a single level .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a new flattened array .
* @ example
*
* _ . flatten ( [ 1 , [ 2 ] , [ 3 , [ [ 4 ] ] ] ] ) ;
* // => [1, 2, 3, 4];
*
* _ . flatten ( [ 1 , [ 2 ] , [ 3 , [ [ 4 ] ] ] ] , true ) ;
* // => [1, 2, 3, [[4]]];
*
* var stooges = [
* { 'name' : 'curly' , 'quotes' : [ 'Oh, a wise guy, eh?' , 'Poifect!' ] } ,
* { 'name' : 'moe' , 'quotes' : [ 'Spread out!' , 'You knucklehead!' ] }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . flatten ( stooges , 'quotes' ) ;
* // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
* /
function flatten ( array , isShallow ) {
return baseFlatten ( array , isShallow ) ;
}
/ * *
* Gets the index at which the first occurrence of ` value ` is found using
* strict equality for comparisons , i . e . ` === ` . If the array is already sorted
* providing ` true ` for ` fromIndex ` will run a faster binary search .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to search .
* @ param { Mixed } value The value to search for .
* @ param { Boolean | Number } [ fromIndex = 0 ] The index to search from or ` true `
* to perform a binary search on a sorted array .
* @ returns { Number } Returns the index of the matched value or ` -1 ` .
* @ example
*
* _ . indexOf ( [ 1 , 2 , 3 , 1 , 2 , 3 ] , 2 ) ;
* // => 1
*
* _ . indexOf ( [ 1 , 2 , 3 , 1 , 2 , 3 ] , 2 , 3 ) ;
* // => 4
*
* _ . indexOf ( [ 1 , 1 , 2 , 2 , 3 , 3 ] , 2 , true ) ;
* // => 2
* /
function indexOf ( array , value , fromIndex ) {
if ( typeof fromIndex == 'number' ) {
var length = array ? array . length : 0 ;
fromIndex = ( fromIndex < 0 ? nativeMax ( 0 , length + fromIndex ) : fromIndex || 0 ) ;
} else if ( fromIndex ) {
var index = sortedIndex ( array , value ) ;
return array [ index ] === value ? index : - 1 ;
}
return array ? baseIndexOf ( array , value , fromIndex ) : - 1 ;
}
/ * *
* Gets all but the last element of an array . If a number ` n ` is provided
* the last ` n ` elements are excluded from the result . If a callback is
* provided elements at the end of the array are excluded from the result
* as long as the callback returns truthy . The callback is bound to ` thisArg `
* and invoked with three arguments ; ( value , index , array ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to query .
* @ param { Function | Object | Number | String } [ callback | n = 1 ] The function called
* per element or the number of elements to exclude . If a property name or
* object is provided it will be used to create a "_.pluck" or "_.where"
* style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a slice of ` array ` .
* @ example
*
* _ . initial ( [ 1 , 2 , 3 ] ) ;
* // => [1, 2]
*
* _ . initial ( [ 1 , 2 , 3 ] , 2 ) ;
* // => [1]
*
* _ . initial ( [ 1 , 2 , 3 ] , function ( num ) {
* return num > 1 ;
* } ) ;
* // => [1]
*
* var food = [
* { 'name' : 'beet' , 'organic' : false } ,
* { 'name' : 'carrot' , 'organic' : true }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . initial ( food , 'organic' ) ;
* // => [{ 'name': 'beet', 'organic': false }]
*
* var food = [
* { 'name' : 'banana' , 'type' : 'fruit' } ,
* { 'name' : 'beet' , 'type' : 'vegetable' } ,
* { 'name' : 'carrot' , 'type' : 'vegetable' }
* ] ;
*
* // using "_.where" callback shorthand
* _ . initial ( food , { 'type' : 'vegetable' } ) ;
* // => [{ 'name': 'banana', 'type': 'fruit' }]
* /
function initial ( array , callback , thisArg ) {
if ( ! array ) {
return [ ] ;
}
var n = 0 ,
length = array . length ;
if ( typeof callback != 'number' && callback != null ) {
var index = length ;
callback = createCallback ( callback , thisArg , 3 ) ;
while ( index -- && callback ( array [ index ] , index , array ) ) {
n ++ ;
}
} else {
n = ( callback == null || thisArg ) ? 1 : callback || n ;
}
return nativeSlice . call ( array , 0 , nativeMin ( nativeMax ( 0 , length - n ) , length ) ) ;
}
/ * *
* Creates an array of unique values present in all provided arrays using
* strict equality for comparisons , i . e . ` === ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } [ array1 , array2 , ... ] The arrays to inspect .
* @ returns { Array } Returns an array of composite values .
* @ example
*
* _ . intersection ( [ 1 , 2 , 3 ] , [ 101 , 2 , 1 , 10 ] , [ 2 , 1 ] ) ;
* // => [1, 2]
* /
function intersection ( array ) {
var args = arguments ,
argsLength = args . length ,
index = - 1 ,
indexOf = getIndexOf ( ) ,
length = array ? array . length : 0 ,
result = [ ] ;
outer :
while ( ++ index < length ) {
var value = array [ index ] ;
if ( indexOf ( result , value ) < 0 ) {
var argsIndex = argsLength ;
while ( -- argsIndex ) {
if ( indexOf ( args [ argsIndex ] , value ) < 0 ) {
continue outer ;
}
}
result . push ( value ) ;
}
}
return result ;
}
/ * *
* Gets the last element of an array . If a number ` n ` is provided the last
* ` n ` elements of the array are returned . If a callback is provided elements
* at the end of the array are returned as long as the callback returns truthy .
* The callback is bound to ` thisArg ` and invoked with three arguments ;
* ( value , index , array ) .
*
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to query .
* @ param { Function | Object | Number | String } [ callback | n ] The function called
* per element or the number of elements to return . If a property name or
* object is provided it will be used to create a "_.pluck" or "_.where"
* style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Mixed } Returns the last element ( s ) of ` array ` .
* @ example
*
* _ . last ( [ 1 , 2 , 3 ] ) ;
* // => 3
*
* _ . last ( [ 1 , 2 , 3 ] , 2 ) ;
* // => [2, 3]
*
* _ . last ( [ 1 , 2 , 3 ] , function ( num ) {
* return num > 1 ;
* } ) ;
* // => [2, 3]
*
* var food = [
* { 'name' : 'beet' , 'organic' : false } ,
* { 'name' : 'carrot' , 'organic' : true }
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . last ( food , 'organic' ) ;
* // => [{ 'name': 'carrot', 'organic': true }]
*
* var food = [
* { 'name' : 'banana' , 'type' : 'fruit' } ,
* { 'name' : 'beet' , 'type' : 'vegetable' } ,
* { 'name' : 'carrot' , 'type' : 'vegetable' }
* ] ;
*
* // using "_.where" callback shorthand
* _ . last ( food , { 'type' : 'vegetable' } ) ;
* // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
* /
function last ( array , callback , thisArg ) {
if ( array ) {
var n = 0 ,
length = array . length ;
if ( typeof callback != 'number' && callback != null ) {
var index = length ;
callback = createCallback ( callback , thisArg , 3 ) ;
while ( index -- && callback ( array [ index ] , index , array ) ) {
n ++ ;
}
} else {
n = callback ;
if ( n == null || thisArg ) {
return array [ length - 1 ] ;
}
}
return nativeSlice . call ( array , nativeMax ( 0 , length - n ) ) ;
}
}
/ * *
* Gets the index at which the last occurrence of ` value ` is found using strict
* equality for comparisons , i . e . ` === ` . If ` fromIndex ` is negative , it is used
* as the offset from the end of the collection .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to search .
* @ param { Mixed } value The value to search for .
* @ param { Number } [ fromIndex = array . length - 1 ] The index to search from .
* @ returns { Number } Returns the index of the matched value or ` -1 ` .
* @ example
*
* _ . lastIndexOf ( [ 1 , 2 , 3 , 1 , 2 , 3 ] , 2 ) ;
* // => 4
*
* _ . lastIndexOf ( [ 1 , 2 , 3 , 1 , 2 , 3 ] , 2 , 3 ) ;
* // => 1
* /
function lastIndexOf ( array , value , fromIndex ) {
var index = array ? array . length : 0 ;
if ( typeof fromIndex == 'number' ) {
index = ( fromIndex < 0 ? nativeMax ( 0 , index + fromIndex ) : nativeMin ( fromIndex , index - 1 ) ) + 1 ;
}
while ( index -- ) {
if ( array [ index ] === value ) {
return index ;
}
}
return - 1 ;
}
/ * *
* Creates an array of numbers ( positive and / or negative ) progressing from
* ` start ` up to but not including ` end ` . If ` start ` is less than ` stop ` a
* zero - length range is created unless a negative ` step ` is specified .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Number } [ start = 0 ] The start of the range .
* @ param { Number } end The end of the range .
* @ param { Number } [ step = 1 ] The value to increment or decrement by .
* @ returns { Array } Returns a new range array .
* @ example
*
* _ . 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 ( 1 , 4 , 0 ) ;
* // => [1, 1, 1]
*
* _ . range ( 0 ) ;
* // => []
* /
function range ( start , end , step ) {
start = + start || 0 ;
step = ( + step || 1 ) ;
if ( end == null ) {
end = start ;
start = 0 ;
}
// use `Array(length)` so engines, like Chakra and V8, avoid slower modes
// http://youtu.be/XAqIpGU8ZZk#t=17m25s
var index = - 1 ,
length = nativeMax ( 0 , ceil ( ( end - start ) / step ) ) ,
result = Array ( length ) ;
while ( ++ index < length ) {
result [ index ] = start ;
start += step ;
}
return result ;
}
/ * *
* The opposite of ` _.initial ` this method gets all but the first value of
* an array . If a number ` n ` is provided the first ` n ` values are excluded
* from the result . If a callback function is provided elements at the beginning
* of the array are excluded from the result as long as the callback returns
* truthy . The callback is bound to ` thisArg ` and invoked with three
* arguments ; ( value , index , array ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias drop , tail
* @ category Arrays
* @ param { Array } array The array to query .
* @ param { Function | Object | Number | String } [ callback | n = 1 ] The function called
* per element or the number of elements to exclude . If a property name or
* object is provided it will be used to create a "_.pluck" or "_.where"
* style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a slice of ` array ` .
* @ example
*
* _ . rest ( [ 1 , 2 , 3 ] ) ;
* // => [2, 3]
*
* _ . rest ( [ 1 , 2 , 3 ] , 2 ) ;
* // => [3]
*
* _ . rest ( [ 1 , 2 , 3 ] , function ( num ) {
* return num < 3 ;
* } ) ;
* // => [3]
*
* var food = [
* { 'name' : 'banana' , 'organic' : true } ,
* { 'name' : 'beet' , 'organic' : false } ,
* ] ;
*
* // using "_.pluck" callback shorthand
* _ . rest ( food , 'organic' ) ;
* // => [{ 'name': 'beet', 'organic': false }]
*
* var food = [
* { 'name' : 'apple' , 'type' : 'fruit' } ,
* { 'name' : 'banana' , 'type' : 'fruit' } ,
* { 'name' : 'beet' , 'type' : 'vegetable' }
* ] ;
*
* // using "_.where" callback shorthand
* _ . rest ( food , { 'type' : 'fruit' } ) ;
* // => [{ 'name': 'beet', 'type': 'vegetable' }]
* /
function rest ( array , callback , thisArg ) {
if ( typeof callback != 'number' && callback != null ) {
var n = 0 ,
index = - 1 ,
length = array ? array . length : 0 ;
callback = createCallback ( callback , thisArg , 3 ) ;
while ( ++ index < length && callback ( array [ index ] , index , array ) ) {
n ++ ;
}
} else {
n = ( callback == null || thisArg ) ? 1 : nativeMax ( 0 , callback ) ;
}
return nativeSlice . call ( array , n ) ;
}
/ * *
* Uses a binary search to determine the smallest index at which a value
* should be inserted into a given sorted array in order to maintain the sort
* order of the array . If a callback is provided it will be executed for
* ` value ` and each element of ` array ` to compute their sort ranking . The
* callback is bound to ` thisArg ` and invoked with one argument ; ( value ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to inspect .
* @ param { Mixed } value The value to evaluate .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Number } Returns the index at which ` value ` should be inserted
* into ` array ` .
* @ example
*
* _ . sortedIndex ( [ 20 , 30 , 50 ] , 40 ) ;
* // => 2
*
* // using "_.pluck" callback shorthand
* _ . sortedIndex ( [ { 'x' : 20 } , { 'x' : 30 } , { 'x' : 50 } ] , { 'x' : 40 } , 'x' ) ;
* // => 2
*
* var dict = {
* 'wordToNumber' : { 'twenty' : 20 , 'thirty' : 30 , 'fourty' : 40 , 'fifty' : 50 }
* } ;
*
* _ . sortedIndex ( [ 'twenty' , 'thirty' , 'fifty' ] , 'fourty' , function ( word ) {
* return dict . wordToNumber [ word ] ;
* } ) ;
* // => 2
*
* _ . sortedIndex ( [ 'twenty' , 'thirty' , 'fifty' ] , 'fourty' , function ( word ) {
* return this . wordToNumber [ word ] ;
* } , dict ) ;
* // => 2
* /
function sortedIndex ( array , value , callback , thisArg ) {
var low = 0 ,
high = array ? array . length : low ;
// explicitly reference `identity` for better inlining in Firefox
callback = callback ? createCallback ( callback , thisArg , 1 ) : identity ;
value = callback ( value ) ;
while ( low < high ) {
var mid = ( low + high ) >>> 1 ;
( callback ( array [ mid ] ) < value )
? low = mid + 1
: high = mid ;
}
return low ;
}
/ * *
* Creates an array of unique values , in order , of the provided arrays using
* strict equality for comparisons , i . e . ` === ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } [ array1 , array2 , ... ] The arrays to inspect .
* @ returns { Array } Returns an array of composite values .
* @ example
*
* _ . union ( [ 1 , 2 , 3 ] , [ 101 , 2 , 1 , 10 ] , [ 2 , 1 ] ) ;
* // => [1, 2, 3, 101, 10]
* /
function union ( array ) {
return baseUniq ( baseFlatten ( arguments , true , true ) ) ;
}
/ * *
* Creates a duplicate - value - free version of an array using strict equality
* for comparisons , i . e . ` === ` . If the array is sorted , providing
* ` true ` for ` isSorted ` will use a faster algorithm . If a callback is provided
* each element of ` array ` is passed through the callback before uniqueness
* is computed . The callback is bound to ` thisArg ` and invoked with three
* arguments ; ( value , index , array ) .
*
* If a property name is provided for ` callback ` the created "_.pluck" style
* callback will return the property value of the given element .
*
* If an object is provided for ` callback ` the created "_.where" style callback
* will return ` true ` for elements that have the properties of the given object ,
* else ` false ` .
*
* @ static
* @ memberOf _
* @ alias unique
* @ category Arrays
* @ param { Array } array The array to process .
* @ param { Boolean } [ isSorted = false ] A flag to indicate that ` array ` is sorted .
* @ param { Function | Object | String } [ callback = identity ] The function called
* per iteration . If a property name or object is provided it will be used
* to create a "_.pluck" or "_.where" style callback , respectively .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns a duplicate - value - free array .
* @ example
*
* _ . uniq ( [ 1 , 2 , 1 , 3 , 1 ] ) ;
* // => [1, 2, 3]
*
* _ . uniq ( [ 1 , 1 , 2 , 2 , 3 ] , true ) ;
* // => [1, 2, 3]
*
* _ . uniq ( [ 'A' , 'b' , 'C' , 'a' , 'B' , 'c' ] , function ( letter ) { return letter . toLowerCase ( ) ; } ) ;
* // => ['A', 'b', 'C']
*
* _ . uniq ( [ 1 , 2.5 , 3 , 1.5 , 2 , 3.5 ] , function ( num ) { return this . floor ( num ) ; } , Math ) ;
* // => [1, 2.5, 3]
*
* // using "_.pluck" callback shorthand
* _ . uniq ( [ { 'x' : 1 } , { 'x' : 2 } , { 'x' : 1 } ] , 'x' ) ;
* // => [{ 'x': 1 }, { 'x': 2 }]
* /
function uniq ( array , isSorted , callback , thisArg ) {
// juggle arguments
if ( typeof isSorted != 'boolean' && isSorted != null ) {
thisArg = callback ;
callback = ! ( thisArg && thisArg [ isSorted ] === array ) ? isSorted : undefined ;
isSorted = false ;
}
if ( callback != null ) {
callback = createCallback ( callback , thisArg , 3 ) ;
}
return baseUniq ( array , isSorted , callback ) ;
}
/ * *
* Creates an array excluding all provided values using strict equality for
* comparisons , i . e . ` === ` .
*
* @ static
* @ memberOf _
* @ category Arrays
* @ param { Array } array The array to filter .
* @ param { Mixed } [ value1 , value2 , ... ] The values to exclude .
* @ returns { Array } Returns a new array of filtered values .
* @ example
*
* _ . without ( [ 1 , 2 , 1 , 0 , 3 , 1 , 4 ] , 0 , 1 ) ;
* // => [2, 3, 4]
* /
function without ( array ) {
return difference ( array , nativeSlice . call ( arguments , 1 ) ) ;
}
/ * *
* Creates an array of grouped elements , the first of which contains the first
* elements of the given arrays , the second of which contains the second
* elements of the given arrays , and so on .
*
* @ static
* @ memberOf _
* @ alias unzip
* @ category Arrays
* @ param { Array } [ array1 , array2 , ... ] Arrays to process .
* @ returns { Array } Returns a new array of grouped elements .
* @ example
*
* _ . zip ( [ 'moe' , 'larry' ] , [ 30 , 40 ] , [ true , false ] ) ;
* // => [['moe', 30, true], ['larry', 40, false]]
* /
function zip ( ) {
var index = - 1 ,
length = max ( pluck ( arguments , 'length' ) ) ,
result = Array ( length < 0 ? 0 : length ) ;
while ( ++ index < length ) {
result [ index ] = pluck ( arguments , index ) ;
}
return result ;
}
/ * *
* Creates an object composed from arrays of ` keys ` and ` values ` . Provide
* either a single two dimensional array , i . e . ` [[key1, value1], [key2, value2]] `
* or two arrays , one of ` keys ` and one of corresponding ` values ` .
*
* @ static
* @ memberOf _
* @ alias object
* @ category Arrays
* @ param { Array } keys The array of keys .
* @ param { Array } [ values = [ ] ] The array of values .
* @ returns { Object } Returns an object composed of the given keys and
* corresponding values .
* @ example
*
* _ . zipObject ( [ 'moe' , 'larry' ] , [ 30 , 40 ] ) ;
* // => { 'moe': 30, 'larry': 40 }
* /
function zipObject ( keys , values ) {
var index = - 1 ,
length = keys ? keys . length : 0 ,
result = { } ;
while ( ++ index < length ) {
var key = keys [ index ] ;
if ( values ) {
result [ key ] = values [ index ] ;
} else if ( key ) {
result [ key [ 0 ] ] = key [ 1 ] ;
}
}
return result ;
}
/*--------------------------------------------------------------------------*/
/ * *
* Creates a function this is restricted to executing ` func ` with the ` this `
* binding and arguments of the created function , only after it is called ` n ` times .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Number } n The number of times the function must be called before
* ` func ` is executed .
* @ param { Function } func The function to restrict .
* @ returns { Function } Returns the new restricted function .
* @ example
*
* var renderNotes = _ . after ( notes . length , render ) ;
* _ . forEach ( notes , function ( note ) {
* note . asyncSave ( { 'success' : renderNotes } ) ;
* } ) ;
* // `renderNotes` is run once, after all notes have saved
* /
function after ( n , func ) {
if ( ! isFunction ( func ) ) {
throw new TypeError ;
}
return function ( ) {
if ( -- n < 1 ) {
return func . apply ( this , arguments ) ;
}
} ;
}
/ * *
* Creates a function that , when called , invokes ` func ` with the ` this `
* binding of ` thisArg ` and prepends any additional ` bind ` arguments to those
* provided to the bound function .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to bind .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` func ` .
* @ param { Mixed } [ arg1 , arg2 , ... ] Arguments to be partially applied .
* @ returns { Function } Returns the new bound function .
* @ example
*
* var func = function ( greeting ) {
* return greeting + ' ' + this . name ;
* } ;
*
* func = _ . bind ( func , { 'name' : 'moe' } , 'hi' ) ;
* func ( ) ;
* // => 'hi moe'
* /
function bind ( func , thisArg ) {
return createBound ( func , 17 , nativeSlice . call ( arguments , 2 ) , null , thisArg ) ;
}
/ * *
* Binds methods of an object to the object itself , overwriting the existing
* method . Method names may be specified as individual arguments or as arrays
* of method names . If no method names are provided all the function properties
* of ` object ` will be bound .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Object } object The object to bind and assign the bound methods to .
* @ param { String } [ methodName1 , methodName2 , ... ] The object method names to
* bind , specified as individual method names or arrays of method names .
* @ returns { Object } Returns ` object ` .
* @ example
*
* var view = {
* 'label' : 'docs' ,
* 'onClick' : function ( ) { console . log ( 'clicked ' + this . label ) ; }
* } ;
*
* _ . bindAll ( view ) ;
* jQuery ( '#docs' ) . on ( 'click' , view . onClick ) ;
* // => logs 'clicked docs', when the button is clicked
* /
function bindAll ( object ) {
var funcs = arguments . length > 1 ? baseFlatten ( arguments , true , false , 1 ) : functions ( object ) ,
index = - 1 ,
length = funcs . length ;
while ( ++ index < length ) {
var key = funcs [ index ] ;
object [ key ] = bind ( object [ key ] , object ) ;
}
return object ;
}
/ * *
* Creates a function that is the composition of the provided functions ,
* where each function consumes the return value of the function that follows .
* For example , composing the functions ` f() ` , ` g() ` , and ` h() ` produces ` f(g(h())) ` .
* Each function is executed with the ` this ` binding of the composed function .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } [ func1 , func2 , ... ] Functions to compose .
* @ returns { Function } Returns the new composed function .
* @ example
*
* var realNameMap = {
* 'curly' : 'jerome'
* } ;
*
* var format = function ( name ) {
* name = realNameMap [ name . toLowerCase ( ) ] || name ;
* return name . charAt ( 0 ) . toUpperCase ( ) + name . slice ( 1 ) . toLowerCase ( ) ;
* } ;
*
* var greet = function ( formatted ) {
* return 'Hiya ' + formatted + '!' ;
* } ;
*
* var welcome = _ . compose ( greet , format ) ;
* welcome ( 'curly' ) ;
* // => 'Hiya Jerome!'
* /
function compose ( ) {
var funcs = arguments ,
length = funcs . length || 1 ;
while ( length -- ) {
if ( ! isFunction ( funcs [ length ] ) ) {
throw new TypeError ;
}
}
return function ( ) {
var args = arguments ,
length = funcs . length ;
while ( length -- ) {
args = [ funcs [ length ] . apply ( this , args ) ] ;
}
return args [ 0 ] ;
} ;
}
/ * *
* Produces a callback bound to an optional ` thisArg ` . If ` func ` is a property
* name the created callback will return the property value for a given element .
* If ` func ` is an object the created callback will return ` true ` for elements
* that contain the equivalent object properties , otherwise it will return ` false ` .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Mixed } [ func = identity ] The value to convert to a callback .
* @ param { Mixed } [ thisArg ] The ` this ` binding of the created callback .
* @ param { Number } [ argCount ] The number of arguments the callback accepts .
* @ returns { Function } Returns a callback function .
* @ example
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 }
* ] ;
*
* // wrap to create custom callback shorthands
* _ . createCallback = _ . wrap ( _ . createCallback , function ( func , callback , thisArg ) {
* var match = /^(.+?)__([gl]t)(.+)$/ . exec ( callback ) ;
* return ! match ? func ( callback , thisArg ) : function ( object ) {
* return match [ 2 ] == 'gt' ? object [ match [ 1 ] ] > match [ 3 ] : object [ match [ 1 ] ] < match [ 3 ] ;
* } ;
* } ) ;
*
* _ . filter ( stooges , 'age__gt45' ) ;
* // => [{ 'name': 'larry', 'age': 50 }]
* /
function createCallback ( func , thisArg , argCount ) {
var type = typeof func ;
if ( func == null || type == 'function' ) {
return baseCreateCallback ( func , thisArg , argCount ) ;
}
// handle "_.pluck" style callback shorthands
if ( type != 'object' ) {
return function ( object ) {
return object [ func ] ;
} ;
}
var props = keys ( func ) ;
return function ( object ) {
var length = props . length ,
result = false ;
while ( length -- ) {
if ( ! ( result = object [ props [ length ] ] === func [ props [ length ] ] ) ) {
break ;
}
}
return result ;
} ;
}
/ * *
* Creates a function that will delay the execution of ` func ` until after
* ` wait ` milliseconds have elapsed since the last time it was invoked .
* Provide an options object to indicate that ` func ` should be invoked on
* the leading and / or trailing edge of the ` wait ` timeout . Subsequent calls
* to the debounced function will return the result of the last ` func ` call .
*
* Note : If ` leading ` and ` trailing ` options are ` true ` ` func ` will be called
* on the trailing edge of the timeout only if the the debounced function is
* invoked more than once during the ` wait ` timeout .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to debounce .
* @ param { Number } wait The number of milliseconds to delay .
* @ param { Object } options The options object .
* [ leading = false ] A boolean to specify execution on the leading edge of the timeout .
* [ maxWait ] The maximum time ` func ` is allowed to be delayed before it ' s called .
* [ trailing = true ] A boolean to specify execution on the trailing edge of the timeout .
* @ returns { Function } Returns the new debounced function .
* @ example
*
* // avoid costly calculations while the window size is in flux
* var lazyLayout = _ . debounce ( calculateLayout , 150 ) ;
* jQuery ( window ) . on ( 'resize' , lazyLayout ) ;
*
* // execute `sendMail` when the click event is fired, debouncing subsequent calls
* jQuery ( '#postbox' ) . on ( 'click' , _ . debounce ( sendMail , 300 , {
* 'leading' : true ,
* 'trailing' : false
* } ) ;
*
* // ensure `batchLog` is executed once after 1 second of debounced calls
* var source = new EventSource ( '/stream' ) ;
* source . addEventListener ( 'message' , _ . debounce ( batchLog , 250 , {
* 'maxWait' : 1000
* } , false ) ;
* /
function debounce ( func , wait , options ) {
var args ,
result ,
thisArg ,
callCount = 0 ,
lastCalled = 0 ,
maxWait = false ,
maxTimeoutId = null ,
timeoutId = null ,
trailing = true ;
if ( ! isFunction ( func ) ) {
throw new TypeError ;
}
wait = nativeMax ( 0 , wait || 0 ) ;
if ( options === true ) {
var leading = true ;
trailing = false ;
} else if ( isObject ( options ) ) {
leading = options . leading ;
maxWait = 'maxWait' in options && nativeMax ( wait , options . maxWait || 0 ) ;
trailing = 'trailing' in options ? options . trailing : trailing ;
}
var clear = function ( ) {
clearTimeout ( maxTimeoutId ) ;
clearTimeout ( timeoutId ) ;
callCount = 0 ;
maxTimeoutId = timeoutId = null ;
} ;
var delayed = function ( ) {
var isCalled = trailing && ( ! leading || callCount > 1 ) ;
clear ( ) ;
if ( isCalled ) {
if ( maxWait !== false ) {
lastCalled = + new Date ;
}
result = func . apply ( thisArg , args ) ;
}
} ;
var maxDelayed = function ( ) {
clear ( ) ;
if ( trailing || ( maxWait !== wait ) ) {
lastCalled = + new Date ;
result = func . apply ( thisArg , args ) ;
}
} ;
return function ( ) {
args = arguments ;
thisArg = this ;
callCount ++ ;
// avoid issues with Titanium and `undefined` timeout ids
// https://github.com/appcelerator/titanium_mobile/blob/3_1_0_GA/android/titanium/src/java/ti/modules/titanium/TitaniumModule.java#L185-L192
clearTimeout ( timeoutId ) ;
if ( maxWait === false ) {
if ( leading && callCount < 2 ) {
result = func . apply ( thisArg , args ) ;
}
} else {
var stamp = + new Date ;
if ( ! maxTimeoutId && ! leading ) {
lastCalled = stamp ;
}
var remaining = maxWait - ( stamp - lastCalled ) ;
if ( remaining <= 0 ) {
clearTimeout ( maxTimeoutId ) ;
maxTimeoutId = null ;
lastCalled = stamp ;
result = func . apply ( thisArg , args ) ;
}
else if ( ! maxTimeoutId ) {
maxTimeoutId = setTimeout ( maxDelayed , remaining ) ;
}
}
if ( wait !== maxWait ) {
timeoutId = setTimeout ( delayed , wait ) ;
}
return result ;
} ;
}
/ * *
* Defers executing the ` func ` function until the current call stack has cleared .
* Additional arguments will be provided to ` func ` when it is invoked .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to defer .
* @ param { Mixed } [ arg1 , arg2 , ... ] Arguments to invoke the function with .
* @ returns { Number } Returns the timer id .
* @ example
*
* _ . defer ( function ( ) { console . log ( 'deferred' ) ; } ) ;
* // returns from the function before 'deferred' is logged
* /
function defer ( func ) {
if ( ! isFunction ( func ) ) {
throw new TypeError ;
}
var args = nativeSlice . call ( arguments , 1 ) ;
return setTimeout ( function ( ) { func . apply ( undefined , args ) ; } , 1 ) ;
}
/ * *
* Executes the ` func ` function after ` wait ` milliseconds . Additional arguments
* will be provided to ` func ` when it is invoked .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to delay .
* @ param { Number } wait The number of milliseconds to delay execution .
* @ param { Mixed } [ arg1 , arg2 , ... ] Arguments to invoke the function with .
* @ returns { Number } Returns the timer id .
* @ example
*
* var log = _ . bind ( console . log , console ) ;
* _ . delay ( log , 1000 , 'logged later' ) ;
* // => 'logged later' (Appears after one second.)
* /
function delay ( func , wait ) {
if ( ! isFunction ( func ) ) {
throw new TypeError ;
}
var args = nativeSlice . call ( arguments , 2 ) ;
return setTimeout ( function ( ) { func . apply ( undefined , args ) ; } , wait ) ;
}
/ * *
* Creates a function that memoizes the result of ` func ` . If ` resolver ` is
* provided it will be used to determine the cache key for storing the result
* based on the arguments provided to the memoized function . By default , the
* first argument provided to the memoized function is used as the cache key .
* The ` func ` is executed with the ` this ` binding of the memoized function .
* The result cache is exposed as the ` cache ` property on the memoized function .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to have its output memoized .
* @ param { Function } [ resolver ] A function used to resolve the cache key .
* @ returns { Function } Returns the new memoizing function .
* @ example
*
* var fibonacci = _ . memoize ( function ( n ) {
* return n < 2 ? n : fibonacci ( n - 1 ) + fibonacci ( n - 2 ) ;
* } ) ;
* /
function memoize ( func , resolver ) {
var cache = { } ;
return function ( ) {
var key = keyPrefix + ( resolver ? resolver . apply ( this , arguments ) : arguments [ 0 ] ) ;
return hasOwnProperty . call ( cache , key )
? cache [ key ]
: ( cache [ key ] = func . apply ( this , arguments ) ) ;
} ;
}
/ * *
* Creates a function that is restricted to execute ` func ` once . Repeat calls to
* the function will return the value of the first call . The ` func ` is executed
* with the ` this ` binding of the created function .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to restrict .
* @ returns { Function } Returns the new restricted function .
* @ example
*
* var initialize = _ . once ( createApplication ) ;
* initialize ( ) ;
* initialize ( ) ;
* // `initialize` executes `createApplication` once
* /
function once ( func ) {
var ran ,
result ;
if ( ! isFunction ( func ) ) {
throw new TypeError ;
}
return function ( ) {
if ( ran ) {
return result ;
}
ran = true ;
result = func . apply ( this , arguments ) ;
// clear the `func` variable so the function may be garbage collected
func = null ;
return result ;
} ;
}
/ * *
* Creates a function that , when called , invokes ` func ` with any additional
* ` partial ` arguments prepended to those provided to the new function . This
* method is similar to ` _.bind ` except it does * * not * * alter the ` this ` binding .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to partially apply arguments to .
* @ param { Mixed } [ arg1 , arg2 , ... ] Arguments to be partially applied .
* @ returns { Function } Returns the new partially applied function .
* @ example
*
* var greet = function ( greeting , name ) { return greeting + ' ' + name ; } ;
* var hi = _ . partial ( greet , 'hi' ) ;
* hi ( 'moe' ) ;
* // => 'hi moe'
* /
function partial ( func ) {
return createBound ( func , 16 , nativeSlice . call ( arguments , 1 ) ) ;
}
/ * *
* Creates a function that , when executed , will only call the ` func ` function
* at most once per every ` wait ` milliseconds . Provide an options object to
* indicate that ` func ` should be invoked on the leading and / or trailing edge
* of the ` wait ` timeout . Subsequent calls to the throttled function will
* return the result of the last ` func ` call .
*
* Note : If ` leading ` and ` trailing ` options are ` true ` ` func ` will be called
* on the trailing edge of the timeout only if the the throttled function is
* invoked more than once during the ` wait ` timeout .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Function } func The function to throttle .
* @ param { Number } wait The number of milliseconds to throttle executions to .
* @ param { Object } options The options object .
* [ leading = true ] A boolean to specify execution on the leading edge of the timeout .
* [ trailing = true ] A boolean to specify execution on the trailing edge of the timeout .
* @ returns { Function } Returns the new throttled function .
* @ example
*
* // avoid excessively updating the position while scrolling
* var throttled = _ . throttle ( updatePosition , 100 ) ;
* jQuery ( window ) . on ( 'scroll' , throttled ) ;
*
* // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
* jQuery ( '.interactive' ) . on ( 'click' , _ . throttle ( renewToken , 300000 , {
* 'trailing' : false
* } ) ) ;
* /
function throttle ( func , wait , options ) {
var leading = true ,
trailing = true ;
if ( options === false ) {
leading = false ;
} else if ( isObject ( options ) ) {
leading = 'leading' in options ? options . leading : leading ;
trailing = 'trailing' in options ? options . trailing : trailing ;
}
options = { } ;
options . leading = leading ;
options . maxWait = wait ;
options . trailing = trailing ;
return debounce ( func , wait , options ) ;
}
/ * *
* Creates a function that provides ` value ` to the wrapper function as its
* first argument . Additional arguments provided to the function are appended
* to those provided to the wrapper function . The wrapper is executed with
* the ` this ` binding of the created function .
*
* @ static
* @ memberOf _
* @ category Functions
* @ param { Mixed } value The value to wrap .
* @ param { Function } wrapper The wrapper function .
* @ returns { Function } Returns the new function .
* @ example
*
* var hello = function ( name ) { return 'hello ' + name ; } ;
* hello = _ . wrap ( hello , function ( func ) {
* return 'before, ' + func ( 'moe' ) + ', after' ;
* } ) ;
* hello ( ) ;
* // => 'before, hello moe, after'
* /
function wrap ( value , wrapper ) {
if ( ! isFunction ( wrapper ) ) {
throw new TypeError ;
}
return function ( ) {
var args = [ value ] ;
push . apply ( args , arguments ) ;
return wrapper . apply ( this , args ) ;
} ;
}
/*--------------------------------------------------------------------------*/
/ * *
* Converts the characters ` & ` , ` < ` , ` > ` , ` " ` , and ` ' ` in ` string ` to their
* corresponding HTML entities .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { String } string The string to escape .
* @ returns { String } Returns the escaped string .
* @ example
*
* _ . escape ( 'Moe, Larry & Curly' ) ;
* // => 'Moe, Larry & Curly'
* /
function escape ( string ) {
return string == null ? '' : String ( string ) . replace ( reUnescapedHtml , escapeHtmlChar ) ;
}
/ * *
* This method returns the first argument provided to it .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { Mixed } value Any value .
* @ returns { Mixed } Returns ` value ` .
* @ example
*
* var moe = { 'name' : 'moe' } ;
* moe === _ . identity ( moe ) ;
* // => true
* /
function identity ( value ) {
return value ;
}
/ * *
* Adds function properties of a source object to the ` lodash ` function and
* chainable wrapper .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { Object } object The object of function properties to add to ` lodash ` .
* @ param { Object } object The object of function properties to add to ` lodash ` .
* @ example
*
* _ . mixin ( {
* 'capitalize' : function ( string ) {
* return string . charAt ( 0 ) . toUpperCase ( ) + string . slice ( 1 ) . toLowerCase ( ) ;
* }
* } ) ;
*
* _ . capitalize ( 'moe' ) ;
* // => 'Moe'
*
* _ ( 'moe' ) . capitalize ( ) ;
* // => 'Moe'
* /
function mixin ( object ) {
forEach ( functions ( object ) , function ( methodName ) {
var func = lodash [ methodName ] = object [ methodName ] ;
lodash . prototype [ methodName ] = function ( ) {
var args = [ this . _ _wrapped _ _ ] ;
push . apply ( args , arguments ) ;
var result = func . apply ( lodash , args ) ;
if ( this . _ _chain _ _ ) {
result = new lodashWrapper ( result ) ;
result . _ _chain _ _ = true ;
}
return result ;
} ;
} ) ;
}
/ * *
* Reverts the '_' variable to its previous value and returns a reference to
* the ` lodash ` function .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ returns { Function } Returns the ` lodash ` function .
* @ example
*
* var lodash = _ . noConflict ( ) ;
* /
function noConflict ( ) {
window . _ = oldDash ;
return this ;
}
/ * *
* Produces a random number between ` min ` and ` max ` ( inclusive ) . If only one
* argument is provided a number between ` 0 ` and the given number will be
* returned .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { Number } [ min = 0 ] The minimum possible value .
* @ param { Number } [ max = 1 ] The maximum possible value .
* @ returns { Number } Returns a random number .
* @ example
*
* _ . random ( 0 , 5 ) ;
* // => a number between 0 and 5
*
* _ . random ( 5 ) ;
* // => also a number between 0 and 5
* /
function random ( min , max ) {
if ( min == null && max == null ) {
max = 1 ;
}
min = + min || 0 ;
if ( max == null ) {
max = min ;
min = 0 ;
} else {
max = + max || 0 ;
}
var rand = nativeRandom ( ) ;
return ( min % 1 || max % 1 )
? min + nativeMin ( rand * ( max - min + parseFloat ( '1e-' + ( ( rand + '' ) . length - 1 ) ) ) , max )
: min + floor ( rand * ( max - min + 1 ) ) ;
}
/ * *
* Resolves the value of ` property ` on ` object ` . If ` property ` is a function
* it will be invoked with the ` this ` binding of ` object ` and its result returned ,
* else the property value is returned . If ` object ` is falsey then ` undefined `
* is returned .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { Object } object The object to inspect .
* @ param { String } property The property to get the value of .
* @ returns { Mixed } Returns the resolved value .
* @ example
*
* var object = {
* 'cheese' : 'crumpets' ,
* 'stuff' : function ( ) {
* return 'nonsense' ;
* }
* } ;
*
* _ . result ( object , 'cheese' ) ;
* // => 'crumpets'
*
* _ . result ( object , 'stuff' ) ;
* // => 'nonsense'
* /
function result ( object , property ) {
var value = object ? object [ property ] : undefined ;
return isFunction ( value ) ? object [ property ] ( ) : value ;
}
/ * *
* A micro - templating method that handles arbitrary delimiters , preserves
* whitespace , and correctly escapes quotes within interpolated code .
*
* Note : In the development build , ` _.template ` utilizes sourceURLs for easier
* debugging . See http : //www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
*
* For more information on precompiling templates see :
* http : //lodash.com/#custom-builds
*
* For more information on Chrome extension sandboxes see :
* http : //developer.chrome.com/stable/extensions/sandboxingEval.html
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { String } text The template text .
* @ param { Object } data The data object used to populate the text .
* @ param { Object } options The options object .
* escape - The "escape" delimiter regexp .
* evaluate - The "evaluate" delimiter regexp .
* imports - An object of properties to import into the compiled template as local variables .
* interpolate - The "interpolate" delimiter regexp .
* sourceURL - The sourceURL of the template ' s compiled source .
* variable - The data object variable name .
* @ returns { Function | String } Returns a compiled function when no ` data ` object
* is given , else it returns the interpolated text .
* @ example
*
* // using a compiled template
* var compiled = _ . template ( 'hello <%= name %>' ) ;
* compiled ( { 'name' : 'moe' } ) ;
* // => 'hello moe'
*
* // using the "escape" delimiter to escape HTML in data property values
* _ . template ( '<b><%- value %></b>' , { 'value' : '<script>' } ) ;
* // => '<b><script></b>'
*
* // using the "evaluate" delimiter to generate HTML
* var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>' ;
* _ . template ( list , { 'people' : [ 'moe' , 'larry' ] } ) ;
* // => '<li>moe</li><li>larry</li>'
*
* // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
* _ . template ( 'hello ${ name }' , { 'name' : 'curly' } ) ;
* // => 'hello curly'
*
* // using the internal `print` function in "evaluate" delimiters
* _ . template ( '<% print("hello " + epithet); %>!' , { 'epithet' : 'stooge' } ) ;
* // => 'hello stooge!'
*
* // using a custom template delimiters
* _ . templateSettings = {
* 'interpolate' : /{{([\s\S]+?)}}/g
* } ;
*
* _ . template ( 'hello {{ name }}!' , { 'name' : 'mustache' } ) ;
* // => 'hello mustache!'
*
* // using the `imports` option to import jQuery
* var list = '<% $.each(people, function(name) { %><li><%= name %></li><% }); %>' ;
* _ . template ( list , { 'people' : [ 'moe' , 'larry' ] } , { 'imports' : { '$' : jQuery } ) ;
* // => '<li>moe</li><li>larry</li>'
*
* // using the `sourceURL` option to specify a custom sourceURL for the template
* var compiled = _ . template ( 'hello <%= name %>' , null , { 'sourceURL' : '/basic/greeting.jst' } ) ;
* compiled ( data ) ;
* // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
*
* // using the `variable` option to ensure a with-statement isn't used in the compiled template
* var compiled = _ . template ( 'hi <%= data.name %>!' , null , { 'variable' : 'data' } ) ;
* compiled . source ;
* // => function(data) {
* var _ _t , _ _p = '' , _ _e = _ . escape ;
* _ _p += 'hi ' + ( ( _ _t = ( data . name ) ) == null ? '' : _ _t ) + '!' ;
* return _ _p ;
* }
*
* // using the `source` property to inline compiled templates for meaningful
* // line numbers in error messages and a stack trace
* fs . writeFileSync ( path . join ( cwd , 'jst.js' ) , ' \
* var JST = { \
* "main" : ' + _.template(mainText).source + ' \
* } ; \
* ' ) ;
* /
function template ( text , data , options ) {
var _ = lodash ,
settings = _ . templateSettings ;
text || ( text = '' ) ;
options = defaults ( { } , options , settings ) ;
var index = 0 ,
source = "__p += '" ,
variable = options . variable ;
var reDelimiters = RegExp (
( options . escape || reNoMatch ) . source + '|' +
( options . interpolate || reNoMatch ) . source + '|' +
( options . evaluate || reNoMatch ) . source + '|$'
, 'g' ) ;
text . replace ( reDelimiters , function ( match , escapeValue , interpolateValue , evaluateValue , offset ) {
source += text . slice ( index , offset ) . replace ( reUnescapedString , escapeStringChar ) ;
if ( escapeValue ) {
source += "' +\n_.escape(" + escapeValue + ") +\n'" ;
}
if ( evaluateValue ) {
source += "';\n" + evaluateValue + ";\n__p += '" ;
}
if ( interpolateValue ) {
source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'" ;
}
index = offset + match . length ;
return match ;
} ) ;
source += "';\n" ;
if ( ! variable ) {
variable = 'obj' ;
source = 'with (' + variable + ' || {}) {\n' + source + '\n}\n' ;
}
source = 'function(' + variable + ') {\n' +
"var __t, __p = '', __j = Array.prototype.join;\n" +
"function print() { __p += __j.call(arguments, '') }\n" +
source +
'return __p\n}' ;
try {
var result = Function ( '_' , 'return ' + source ) ( _ ) ;
} catch ( e ) {
e . source = source ;
throw e ;
}
if ( data ) {
return result ( data ) ;
}
result . source = source ;
return result ;
}
/ * *
* Executes the callback ` n ` times , returning an array of the results
* of each callback execution . The callback is bound to ` thisArg ` and invoked
* with one argument ; ( index ) .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { Number } n The number of times to execute the callback .
* @ param { Function } callback The function called per iteration .
* @ param { Mixed } [ thisArg ] The ` this ` binding of ` callback ` .
* @ returns { Array } Returns an array of the results of each ` callback ` execution .
* @ example
*
* var diceRolls = _ . times ( 3 , _ . partial ( _ . random , 1 , 6 ) ) ;
* // => [3, 6, 4]
*
* _ . times ( 3 , function ( n ) { mage . castSpell ( n ) ; } ) ;
* // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
*
* _ . times ( 3 , function ( n ) { this . cast ( n ) ; } , mage ) ;
* // => also calls `mage.castSpell(n)` three times
* /
function times ( n , callback , thisArg ) {
var index = - 1 ,
result = Array ( n > - 1 ? n : 0 ) ;
while ( ++ index < n ) {
result [ index ] = callback . call ( thisArg , index ) ;
}
return result ;
}
/ * *
* The inverse of ` _.escape ` this method converts the HTML entities
* ` & ` , ` < ` , ` > ` , ` " ` , and ` ' ` in ` string ` to their
* corresponding characters .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { String } string The string to unescape .
* @ returns { String } Returns the unescaped string .
* @ example
*
* _ . unescape ( 'Moe, Larry & Curly' ) ;
* // => 'Moe, Larry & Curly'
* /
function unescape ( string ) {
return string == null ? '' : String ( string ) . replace ( reEscapedHtml , unescapeHtmlChar ) ;
}
/ * *
* Generates a unique ID . If ` prefix ` is provided the ID will be appended to it .
*
* @ static
* @ memberOf _
* @ category Utilities
* @ param { String } [ prefix ] The value to prefix the ID with .
* @ returns { String } Returns the unique ID .
* @ example
*
* _ . uniqueId ( 'contact_' ) ;
* // => 'contact_104'
*
* _ . uniqueId ( ) ;
* // => '105'
* /
function uniqueId ( prefix ) {
var id = ++ idCounter + '' ;
return prefix ? prefix + id : id ;
}
/*--------------------------------------------------------------------------*/
/ * *
* Creates a ` lodash ` object that wraps the given ` value ` .
*
* @ static
* @ memberOf _
* @ category Chaining
* @ param { Mixed } value The value to wrap .
* @ returns { Object } Returns the wrapper object .
* @ example
*
* var stooges = [
* { 'name' : 'moe' , 'age' : 40 } ,
* { 'name' : 'larry' , 'age' : 50 } ,
* { 'name' : 'curly' , 'age' : 60 }
* ] ;
*
* var youngest = _ . chain ( stooges )
* . sortBy ( function ( stooge ) { return stooge . age ; } )
* . map ( function ( stooge ) { return stooge . name + ' is ' + stooge . age ; } )
* . first ( ) ;
* // => 'moe is 40'
* /
function chain ( value ) {
value = new lodashWrapper ( value ) ;
value . _ _chain _ _ = true ;
return value ;
}
/ * *
* Invokes ` interceptor ` with the ` value ` as the first argument and then
* returns ` value ` . The purpose of this method is to "tap into" a method
* chain in order to perform operations on intermediate results within
* the chain .
*
* @ static
* @ memberOf _
* @ category Chaining
* @ param { Mixed } value The value to provide to ` interceptor ` .
* @ param { Function } interceptor The function to invoke .
* @ returns { Mixed } Returns ` value ` .
* @ example
*
* _ ( [ 1 , 2 , 3 , 4 ] )
* . filter ( function ( num ) { return num % 2 == 0 ; } )
* . tap ( function ( array ) { console . log ( array ) ; } )
* . map ( function ( num ) { return num * num ; } )
* . value ( ) ;
* // => // [2, 4] (logged)
* // => [4, 16]
* /
function tap ( value , interceptor ) {
interceptor ( value ) ;
return value ;
}
/ * *
* Enables method chaining on the wrapper object .
*
* @ name chain
* @ memberOf _
* @ category Chaining
* @ returns { Mixed } Returns the wrapper object .
* @ example
*
* var sum = _ ( [ 1 , 2 , 3 ] )
* . chain ( )
* . reduce ( function ( sum , num ) { return sum + num ; } )
* . value ( )
* // => 6`
* /
function wrapperChain ( ) {
this . _ _chain _ _ = true ;
return this ;
}
/ * *
* Extracts the wrapped value .
*
* @ name valueOf
* @ memberOf _
* @ alias value
* @ category Chaining
* @ returns { Mixed } Returns the wrapped value .
* @ example
*
* _ ( [ 1 , 2 , 3 ] ) . valueOf ( ) ;
* // => [1, 2, 3]
* /
function wrapperValueOf ( ) {
return this . _ _wrapped _ _ ;
}
/*--------------------------------------------------------------------------*/
// add functions that return wrapped values when chaining
lodash . after = after ;
lodash . bind = bind ;
lodash . bindAll = bindAll ;
lodash . chain = chain ;
lodash . compact = compact ;
lodash . compose = compose ;
lodash . countBy = countBy ;
lodash . debounce = debounce ;
lodash . defaults = defaults ;
lodash . defer = defer ;
lodash . delay = delay ;
lodash . difference = difference ;
lodash . filter = filter ;
lodash . flatten = flatten ;
lodash . forEach = forEach ;
lodash . functions = functions ;
lodash . groupBy = groupBy ;
lodash . initial = initial ;
lodash . intersection = intersection ;
lodash . invert = invert ;
lodash . invoke = invoke ;
lodash . keys = keys ;
lodash . map = map ;
lodash . max = max ;
lodash . memoize = memoize ;
lodash . min = min ;
lodash . omit = omit ;
lodash . once = once ;
lodash . pairs = pairs ;
lodash . partial = partial ;
lodash . pick = pick ;
lodash . pluck = pluck ;
lodash . range = range ;
lodash . reject = reject ;
lodash . rest = rest ;
lodash . shuffle = shuffle ;
lodash . sortBy = sortBy ;
lodash . tap = tap ;
lodash . throttle = throttle ;
lodash . times = times ;
lodash . toArray = toArray ;
lodash . union = union ;
lodash . uniq = uniq ;
lodash . values = values ;
lodash . where = where ;
lodash . without = without ;
lodash . wrap = wrap ;
lodash . zip = zip ;
// add aliases
lodash . collect = map ;
lodash . drop = rest ;
lodash . each = forEach ;
lodash . extend = assign ;
lodash . methods = functions ;
lodash . object = zipObject ;
lodash . select = filter ;
lodash . tail = rest ;
lodash . unique = uniq ;
/*--------------------------------------------------------------------------*/
// add functions that return unwrapped values when chaining
lodash . clone = clone ;
lodash . contains = contains ;
lodash . escape = escape ;
lodash . every = every ;
lodash . find = find ;
lodash . has = has ;
lodash . identity = identity ;
lodash . indexOf = indexOf ;
lodash . isArguments = isArguments ;
lodash . isArray = isArray ;
lodash . isBoolean = isBoolean ;
lodash . isDate = isDate ;
lodash . isElement = isElement ;
lodash . isEmpty = isEmpty ;
lodash . isEqual = isEqual ;
lodash . isFinite = isFinite ;
lodash . isFunction = isFunction ;
lodash . isNaN = isNaN ;
lodash . isNull = isNull ;
lodash . isNumber = isNumber ;
lodash . isObject = isObject ;
lodash . isRegExp = isRegExp ;
lodash . isString = isString ;
lodash . isUndefined = isUndefined ;
lodash . lastIndexOf = lastIndexOf ;
lodash . mixin = mixin ;
lodash . noConflict = noConflict ;
lodash . random = random ;
lodash . reduce = reduce ;
lodash . reduceRight = reduceRight ;
lodash . result = result ;
lodash . size = size ;
lodash . some = some ;
lodash . sortedIndex = sortedIndex ;
lodash . template = template ;
lodash . unescape = unescape ;
lodash . uniqueId = uniqueId ;
// add aliases
lodash . all = every ;
lodash . any = some ;
lodash . detect = find ;
lodash . findWhere = findWhere ;
lodash . foldl = reduce ;
lodash . foldr = reduceRight ;
lodash . include = contains ;
lodash . inject = reduce ;
/*--------------------------------------------------------------------------*/
// add functions capable of returning wrapped and unwrapped values when chaining
lodash . first = first ;
lodash . last = last ;
// add aliases
lodash . take = first ;
lodash . head = first ;
/*--------------------------------------------------------------------------*/
// add functions to `lodash.prototype`
mixin ( lodash ) ;
/ * *
* The semantic version number .
*
* @ static
* @ memberOf _
* @ type String
* /
lodash . VERSION = '1.3.1' ;
// add "Chaining" functions to the wrapper
lodash . prototype . chain = wrapperChain ;
lodash . prototype . value = wrapperValueOf ;
// add `Array` mutator functions to the wrapper
forEach ( [ 'pop' , 'push' , 'reverse' , 'shift' , 'sort' , 'splice' , 'unshift' ] , function ( methodName ) {
var func = arrayRef [ methodName ] ;
lodash . prototype [ methodName ] = function ( ) {
var value = this . _ _wrapped _ _ ;
func . apply ( value , arguments ) ;
// avoid array-like object bugs with `Array#shift` and `Array#splice`
// in Firefox < 10 and IE < 9
if ( ! support . spliceObjects && value . length === 0 ) {
delete value [ 0 ] ;
}
return this ;
} ;
} ) ;
// add `Array` accessor functions to the wrapper
forEach ( [ 'concat' , 'join' , 'slice' ] , function ( methodName ) {
var func = arrayRef [ methodName ] ;
lodash . prototype [ methodName ] = function ( ) {
var value = this . _ _wrapped _ _ ,
result = func . apply ( value , arguments ) ;
if ( this . _ _chain _ _ ) {
result = new lodashWrapper ( result ) ;
result . _ _chain _ _ = true ;
}
return result ;
} ;
} ) ;
/*--------------------------------------------------------------------------*/
// some AMD build optimizers, like r.js, check for specific condition patterns like the following:
if ( typeof define == 'function' && typeof define . amd == 'object' && define . amd ) {
// Expose Lo-Dash to the global object even when an AMD loader is present in
// case Lo-Dash was injected by a third-party script and not intended to be
// loaded as a module. The global assignment can be reverted in the Lo-Dash
// module via its `noConflict()` method.
window . _ = lodash ;
// define as an anonymous module so, through path mapping, it can be
// referenced as the "underscore" module
define ( function ( ) {
return lodash ;
} ) ;
}
// check for `exports` after `define` in case a build optimizer adds an `exports` object
else if ( freeExports && ! freeExports . nodeType ) {
// in Node.js or RingoJS v0.8.0+
if ( freeModule ) {
( freeModule . exports = lodash ) . _ = lodash ;
}
// in Narwhal or RingoJS v0.7.0-
else {
freeExports . _ = lodash ;
}
}
else {
// in a browser or Rhino
window . _ = lodash ;
}
} ( this ) ) ;