lodash.underscore.js 132 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307
  1. /**
  2. * @license
  3. * Lo-Dash 1.0.2 (Custom Build) <http://lodash.com/>
  4. * Build: `lodash underscore -o ./dist/lodash.underscore.js`
  5. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  6. * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
  7. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
  8. * Available under MIT license <http://lodash.com/license>
  9. */
  10. ;(function(window, undefined) {
  11. /** Detect free variable `exports` */
  12. var freeExports = typeof exports == 'object' && exports;
  13. /** Detect free variable `module` */
  14. var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
  15. /** Detect free variable `global` and use it as `window` */
  16. var freeGlobal = typeof global == 'object' && global;
  17. if (freeGlobal.global === freeGlobal) {
  18. window = freeGlobal;
  19. }
  20. /** Used for array and object method references */
  21. var arrayRef = [],
  22. objectRef = {};
  23. /** Used to generate unique IDs */
  24. var idCounter = 0;
  25. /** Used internally to indicate various things */
  26. var indicatorObject = objectRef;
  27. /** Used to restore the original `_` reference in `noConflict` */
  28. var oldDash = window._;
  29. /** Used to match HTML entities */
  30. var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
  31. /** Used to match empty string literals in compiled template source */
  32. var reEmptyStringLeading = /\b__p \+= '';/g,
  33. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  34. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  35. /** Used to match regexp flags from their coerced string values */
  36. var reFlags = /\w*$/;
  37. /** Used to detect if a method is native */
  38. var reNative = RegExp('^' +
  39. (objectRef.valueOf + '')
  40. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  41. .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
  42. );
  43. /**
  44. * Used to match ES6 template delimiters
  45. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
  46. */
  47. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  48. /** Used to match "interpolate" template delimiters */
  49. var reInterpolate = /<%=([\s\S]+?)%>/g;
  50. /** Used to ensure capturing order of template delimiters */
  51. var reNoMatch = /($^)/;
  52. /** Used to match HTML characters */
  53. var reUnescapedHtml = /[&<>"']/g;
  54. /** Used to match unescaped characters in compiled string literals */
  55. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  56. /** Used to make template sourceURLs easier to identify */
  57. var templateCounter = 0;
  58. /** Native method shortcuts */
  59. var ceil = Math.ceil,
  60. concat = arrayRef.concat,
  61. floor = Math.floor,
  62. hasOwnProperty = objectRef.hasOwnProperty,
  63. push = arrayRef.push,
  64. toString = objectRef.toString;
  65. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  66. var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
  67. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  68. nativeIsFinite = window.isFinite,
  69. nativeIsNaN = window.isNaN,
  70. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  71. nativeMax = Math.max,
  72. nativeMin = Math.min,
  73. nativeRandom = Math.random;
  74. /** `Object#toString` result shortcuts */
  75. var argsClass = '[object Arguments]',
  76. arrayClass = '[object Array]',
  77. boolClass = '[object Boolean]',
  78. dateClass = '[object Date]',
  79. funcClass = '[object Function]',
  80. numberClass = '[object Number]',
  81. objectClass = '[object Object]',
  82. regexpClass = '[object RegExp]',
  83. stringClass = '[object String]';
  84. /** Detect various environments */
  85. var isIeOpera = !!window.attachEvent,
  86. isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
  87. /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */
  88. var isBindFast = nativeBind && !isV8;
  89. /**
  90. * Detect if `Array#shift` and `Array#splice` augment array-like objects
  91. * incorrectly:
  92. *
  93. * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
  94. * and `splice()` functions that fail to remove the last element, `value[0]`,
  95. * of array-like objects even though the `length` property is set to `0`.
  96. * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
  97. * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
  98. */
  99. var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 },
  100. arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
  101. /** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */
  102. var argsAreObjects = arguments.constructor == Object;
  103. /** Used to determine if values are of the language type Object */
  104. var objectTypes = {
  105. 'boolean': false,
  106. 'function': true,
  107. 'object': true,
  108. 'number': false,
  109. 'string': false,
  110. 'undefined': false
  111. };
  112. /** Used to escape characters for inclusion in compiled string literals */
  113. var stringEscapes = {
  114. '\\': '\\',
  115. "'": "'",
  116. '\n': 'n',
  117. '\r': 'r',
  118. '\t': 't',
  119. '\u2028': 'u2028',
  120. '\u2029': 'u2029'
  121. };
  122. /*--------------------------------------------------------------------------*/
  123. /**
  124. * Creates a `lodash` object, that wraps the given `value`, to enable method
  125. * chaining.
  126. *
  127. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  128. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  129. * and `unshift`
  130. *
  131. * The chainable wrapper functions are:
  132. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
  133. * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
  134. * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
  135. * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
  136. * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
  137. * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
  138. * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
  139. * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
  140. *
  141. * The non-chainable wrapper functions are:
  142. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
  143. * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`,
  144. * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`,
  145. * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`,
  146. * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`,
  147. * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId`
  148. *
  149. * The wrapper functions `first` and `last` return wrapped values when `n` is
  150. * passed, otherwise they return unwrapped values.
  151. *
  152. * @name _
  153. * @constructor
  154. * @category Chaining
  155. * @param {Mixed} value The value to wrap in a `lodash` instance.
  156. * @returns {Object} Returns a `lodash` instance.
  157. */
  158. function lodash(value) {
  159. // exit early if already wrapped, even if wrapped by a different `lodash` constructor
  160. if (value && typeof value == 'object' && value.__wrapped__) {
  161. return value;
  162. }
  163. // allow invoking `lodash` without the `new` operator
  164. if (!(this instanceof lodash)) {
  165. return new lodash(value);
  166. }
  167. this.__wrapped__ = value;
  168. }
  169. /**
  170. * By default, the template delimiters used by Lo-Dash are similar to those in
  171. * embedded Ruby (ERB). Change the following template settings to use alternative
  172. * delimiters.
  173. *
  174. * @static
  175. * @memberOf _
  176. * @type Object
  177. */
  178. lodash.templateSettings = {
  179. /**
  180. * Used to detect `data` property values to be HTML-escaped.
  181. *
  182. * @memberOf _.templateSettings
  183. * @type RegExp
  184. */
  185. 'escape': /<%-([\s\S]+?)%>/g,
  186. /**
  187. * Used to detect code to be evaluated.
  188. *
  189. * @memberOf _.templateSettings
  190. * @type RegExp
  191. */
  192. 'evaluate': /<%([\s\S]+?)%>/g,
  193. /**
  194. * Used to detect `data` property values to inject.
  195. *
  196. * @memberOf _.templateSettings
  197. * @type RegExp
  198. */
  199. 'interpolate': reInterpolate,
  200. /**
  201. * Used to reference the data object in the template text.
  202. *
  203. * @memberOf _.templateSettings
  204. * @type String
  205. */
  206. 'variable': ''
  207. };
  208. /*--------------------------------------------------------------------------*/
  209. /**
  210. * Used by `_.max` and `_.min` as the default `callback` when a given
  211. * `collection` is a string value.
  212. *
  213. * @private
  214. * @param {String} value The character to inspect.
  215. * @returns {Number} Returns the code unit of given character.
  216. */
  217. function charAtCallback(value) {
  218. return value.charCodeAt(0);
  219. }
  220. /**
  221. * Used by `sortBy` to compare transformed `collection` values, stable sorting
  222. * them in ascending order.
  223. *
  224. * @private
  225. * @param {Object} a The object to compare to `b`.
  226. * @param {Object} b The object to compare to `a`.
  227. * @returns {Number} Returns the sort order indicator of `1` or `-1`.
  228. */
  229. function compareAscending(a, b) {
  230. var ai = a.index,
  231. bi = b.index;
  232. a = a.criteria;
  233. b = b.criteria;
  234. // ensure a stable sort in V8 and other engines
  235. // http://code.google.com/p/v8/issues/detail?id=90
  236. if (a !== b) {
  237. if (a > b || typeof a == 'undefined') {
  238. return 1;
  239. }
  240. if (a < b || typeof b == 'undefined') {
  241. return -1;
  242. }
  243. }
  244. return ai < bi ? -1 : 1;
  245. }
  246. /**
  247. * Creates a function that, when called, invokes `func` with the `this` binding
  248. * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
  249. * bound function.
  250. *
  251. * @private
  252. * @param {Function|String} func The function to bind or the method name.
  253. * @param {Mixed} [thisArg] The `this` binding of `func`.
  254. * @param {Array} partialArgs An array of arguments to be partially applied.
  255. * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
  256. * @returns {Function} Returns the new bound function.
  257. */
  258. function createBound(func, thisArg, partialArgs, rightIndicator) {
  259. var isFunc = isFunction(func),
  260. isPartial = !partialArgs,
  261. key = thisArg;
  262. // juggle arguments
  263. if (isPartial) {
  264. partialArgs = thisArg;
  265. }
  266. if (!isFunc) {
  267. thisArg = func;
  268. }
  269. function bound() {
  270. // `Function#bind` spec
  271. // http://es5.github.com/#x15.3.4.5
  272. var args = arguments,
  273. thisBinding = isPartial ? this : thisArg;
  274. if (!isFunc) {
  275. func = thisArg[key];
  276. }
  277. if (partialArgs.length) {
  278. args = args.length
  279. ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
  280. : partialArgs;
  281. }
  282. if (this instanceof bound) {
  283. // ensure `new bound` is an instance of `bound` and `func`
  284. noop.prototype = func.prototype;
  285. thisBinding = new noop;
  286. noop.prototype = null;
  287. // mimic the constructor's `return` behavior
  288. // http://es5.github.com/#x13.2.2
  289. var result = func.apply(thisBinding, args);
  290. return isObject(result) ? result : thisBinding;
  291. }
  292. return func.apply(thisBinding, args);
  293. }
  294. return bound;
  295. }
  296. /**
  297. * Produces a callback bound to an optional `thisArg`. If `func` is a property
  298. * name, the created callback will return the property value for a given element.
  299. * If `func` is an object, the created callback will return `true` for elements
  300. * that contain the equivalent object properties, otherwise it will return `false`.
  301. *
  302. * @private
  303. * @param {Mixed} [func=identity] The value to convert to a callback.
  304. * @param {Mixed} [thisArg] The `this` binding of the created callback.
  305. * @param {Number} [argCount=3] The number of arguments the callback accepts.
  306. * @returns {Function} Returns a callback function.
  307. */
  308. function createCallback(func, thisArg, argCount) {
  309. if (func == null) {
  310. return identity;
  311. }
  312. var type = typeof func;
  313. if (type != 'function') {
  314. if (type != 'object') {
  315. return function(object) {
  316. return object[func];
  317. };
  318. }
  319. var props = keys(func);
  320. return function(object) {
  321. var length = props.length,
  322. result = false;
  323. while (length--) {
  324. if (!(result = object[props[length]] === func[props[length]])) {
  325. break;
  326. }
  327. }
  328. return result;
  329. };
  330. }
  331. if (typeof thisArg != 'undefined') {
  332. if (argCount === 1) {
  333. return function(value) {
  334. return func.call(thisArg, value);
  335. };
  336. }
  337. if (argCount === 2) {
  338. return function(a, b) {
  339. return func.call(thisArg, a, b);
  340. };
  341. }
  342. if (argCount === 4) {
  343. return function(accumulator, value, index, object) {
  344. return func.call(thisArg, accumulator, value, index, object);
  345. };
  346. }
  347. return function(value, index, object) {
  348. return func.call(thisArg, value, index, object);
  349. };
  350. }
  351. return func;
  352. }
  353. /**
  354. * A function compiled to iterate `arguments` objects, arrays, objects, and
  355. * strings consistenly across environments, executing the `callback` for each
  356. * element in the `collection`. The `callback` is bound to `thisArg` and invoked
  357. * with three arguments; (value, index|key, collection). Callbacks may exit
  358. * iteration early by explicitly returning `false`.
  359. *
  360. * @private
  361. * @type Function
  362. * @param {Array|Object|String} collection The collection to iterate over.
  363. * @param {Function} [callback=identity] The function called per iteration.
  364. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  365. * @returns {Array|Object|String} Returns `collection`.
  366. */
  367. var each = function (collection, callback, thisArg) {
  368. var index, iterable = collection, result = iterable;
  369. if (!iterable) return result;
  370. callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg);
  371. var length = iterable.length; index = -1;
  372. if (typeof length == 'number') {
  373. while (++index < length) {
  374. if (callback(iterable[index], index, collection) === indicatorObject) return result
  375. }
  376. }
  377. else {
  378. for (index in iterable) {
  379. if (hasOwnProperty.call(iterable, index)) {
  380. if (callback(iterable[index], index, collection) === indicatorObject) return result;
  381. }
  382. }
  383. }
  384. };
  385. /**
  386. * Used by `template` to escape characters for inclusion in compiled
  387. * string literals.
  388. *
  389. * @private
  390. * @param {String} match The matched character to escape.
  391. * @returns {String} Returns the escaped character.
  392. */
  393. function escapeStringChar(match) {
  394. return '\\' + stringEscapes[match];
  395. }
  396. /**
  397. * Used by `escape` to convert characters to HTML entities.
  398. *
  399. * @private
  400. * @param {String} match The matched character to escape.
  401. * @returns {String} Returns the escaped character.
  402. */
  403. function escapeHtmlChar(match) {
  404. return htmlEscapes[match];
  405. }
  406. /**
  407. * Checks if `value` is a DOM node in IE < 9.
  408. *
  409. * @private
  410. * @param {Mixed} value The value to check.
  411. * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
  412. */
  413. function isNode(value) {
  414. // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
  415. // methods that are `typeof` "string" and still can coerce nodes to strings
  416. return typeof value.toString != 'function' && typeof (value + '') == 'string';
  417. }
  418. /**
  419. * A no-operation function.
  420. *
  421. * @private
  422. */
  423. function noop() {
  424. // no operation performed
  425. }
  426. /**
  427. * Slices the `collection` from the `start` index up to, but not including,
  428. * the `end` index.
  429. *
  430. * Note: This function is used, instead of `Array#slice`, to support node lists
  431. * in IE < 9 and to ensure dense arrays are returned.
  432. *
  433. * @private
  434. * @param {Array|Object|String} collection The collection to slice.
  435. * @param {Number} start The start index.
  436. * @param {Number} end The end index.
  437. * @returns {Array} Returns the new array.
  438. */
  439. function slice(array, start, end) {
  440. start || (start = 0);
  441. if (typeof end == 'undefined') {
  442. end = array ? array.length : 0;
  443. }
  444. var index = -1,
  445. length = end - start || 0,
  446. result = Array(length < 0 ? 0 : length);
  447. while (++index < length) {
  448. result[index] = array[start + index];
  449. }
  450. return result;
  451. }
  452. /**
  453. * Used by `unescape` to convert HTML entities to characters.
  454. *
  455. * @private
  456. * @param {String} match The matched character to unescape.
  457. * @returns {String} Returns the unescaped character.
  458. */
  459. function unescapeHtmlChar(match) {
  460. return htmlUnescapes[match];
  461. }
  462. /*--------------------------------------------------------------------------*/
  463. /**
  464. * Checks if `value` is an `arguments` object.
  465. *
  466. * @static
  467. * @memberOf _
  468. * @category Objects
  469. * @param {Mixed} value The value to check.
  470. * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
  471. * @example
  472. *
  473. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  474. * // => true
  475. *
  476. * _.isArguments([1, 2, 3]);
  477. * // => false
  478. */
  479. function isArguments(value) {
  480. return toString.call(value) == argsClass;
  481. }
  482. // fallback for browsers that can't detect `arguments` objects by [[Class]]
  483. if (!isArguments(arguments)) {
  484. isArguments = function(value) {
  485. return value ? hasOwnProperty.call(value, 'callee') : false;
  486. };
  487. }
  488. /**
  489. * Iterates over `object`'s own and inherited enumerable properties, executing
  490. * the `callback` for each property. The `callback` is bound to `thisArg` and
  491. * invoked with three arguments; (value, key, object). Callbacks may exit iteration
  492. * early by explicitly returning `false`.
  493. *
  494. * @static
  495. * @memberOf _
  496. * @type Function
  497. * @category Objects
  498. * @param {Object} object The object to iterate over.
  499. * @param {Function} [callback=identity] The function called per iteration.
  500. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  501. * @returns {Object} Returns `object`.
  502. * @example
  503. *
  504. * function Dog(name) {
  505. * this.name = name;
  506. * }
  507. *
  508. * Dog.prototype.bark = function() {
  509. * alert('Woof, woof!');
  510. * };
  511. *
  512. * _.forIn(new Dog('Dagny'), function(value, key) {
  513. * alert(key);
  514. * });
  515. * // => alerts 'name' and 'bark' (order is not guaranteed)
  516. */
  517. var forIn = function (collection, callback) {
  518. var index, iterable = collection, result = iterable;
  519. if (!iterable) return result;
  520. if (!objectTypes[typeof iterable]) return result;
  521. callback || (callback = identity);
  522. for (index in iterable) {
  523. if (callback(iterable[index], index, collection) === indicatorObject) return result;
  524. }
  525. return result
  526. };
  527. /**
  528. * Iterates over an object's own enumerable properties, executing the `callback`
  529. * for each property. The `callback` is bound to `thisArg` and invoked with three
  530. * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
  531. * returning `false`.
  532. *
  533. * @static
  534. * @memberOf _
  535. * @type Function
  536. * @category Objects
  537. * @param {Object} object The object to iterate over.
  538. * @param {Function} [callback=identity] The function called per iteration.
  539. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  540. * @returns {Object} Returns `object`.
  541. * @example
  542. *
  543. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  544. * alert(key);
  545. * });
  546. * // => alerts '0', '1', and 'length' (order is not guaranteed)
  547. */
  548. var forOwn = function (collection, callback) {
  549. var index, iterable = collection, result = iterable;
  550. if (!iterable) return result;
  551. if (!objectTypes[typeof iterable]) return result;
  552. callback || (callback = identity);
  553. for (index in iterable) {
  554. if (hasOwnProperty.call(iterable, index)) {
  555. if (callback(iterable[index], index, collection) === indicatorObject) return result;
  556. }
  557. }
  558. return result
  559. };
  560. /**
  561. * Checks if `value` is an array.
  562. *
  563. * @static
  564. * @memberOf _
  565. * @category Objects
  566. * @param {Mixed} value The value to check.
  567. * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
  568. * @example
  569. *
  570. * (function() { return _.isArray(arguments); })();
  571. * // => false
  572. *
  573. * _.isArray([1, 2, 3]);
  574. * // => true
  575. */
  576. var isArray = nativeIsArray || function(value) {
  577. // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
  578. // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
  579. return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass;
  580. };
  581. /**
  582. * Creates an array composed of the own enumerable property names of `object`.
  583. *
  584. * @static
  585. * @memberOf _
  586. * @category Objects
  587. * @param {Object} object The object to inspect.
  588. * @returns {Array} Returns a new array of property names.
  589. * @example
  590. *
  591. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  592. * // => ['one', 'two', 'three'] (order is not guaranteed)
  593. */
  594. var keys = !nativeKeys ? shimKeys : function(object) {
  595. if (!isObject(object)) {
  596. return [];
  597. }
  598. return nativeKeys(object);
  599. };
  600. /**
  601. * A fallback implementation of `isPlainObject` that checks if a given `value`
  602. * is an object created by the `Object` constructor, assuming objects created
  603. * by the `Object` constructor have no inherited enumerable properties and that
  604. * there are no `Object.prototype` extensions.
  605. *
  606. * @private
  607. * @param {Mixed} value The value to check.
  608. * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
  609. */
  610. function shimIsPlainObject(value) {
  611. // avoid non-objects and false positives for `arguments` objects
  612. var result = false;
  613. if (!(value && typeof value == 'object') || isArguments(value)) {
  614. return result;
  615. }
  616. // check that the constructor is `Object` (i.e. `Object instanceof Object`)
  617. var ctor = value.constructor;
  618. if ((!isFunction(ctor)) || ctor instanceof ctor) {
  619. // In most environments an object's own properties are iterated before
  620. // its inherited properties. If the last iterated property is an object's
  621. // own property then there are no inherited enumerable properties.
  622. forIn(value, function(value, key) {
  623. result = key;
  624. });
  625. return result === false || hasOwnProperty.call(value, result);
  626. }
  627. return result;
  628. }
  629. /**
  630. * A fallback implementation of `Object.keys` that produces an array of the
  631. * given object's own enumerable property names.
  632. *
  633. * @private
  634. * @param {Object} object The object to inspect.
  635. * @returns {Array} Returns a new array of property names.
  636. */
  637. function shimKeys(object) {
  638. var result = [];
  639. forOwn(object, function(value, key) {
  640. result.push(key);
  641. });
  642. return result;
  643. }
  644. /**
  645. * Used to convert characters to HTML entities:
  646. *
  647. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  648. * don't require escaping in HTML and have no special meaning unless they're part
  649. * of a tag or an unquoted attribute value.
  650. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  651. */
  652. var htmlEscapes = {
  653. '&': '&amp;',
  654. '<': '&lt;',
  655. '>': '&gt;',
  656. '"': '&quot;',
  657. "'": '&#39;'
  658. };
  659. /** Used to convert HTML entities to characters */
  660. var htmlUnescapes = invert(htmlEscapes);
  661. /*--------------------------------------------------------------------------*/
  662. /**
  663. * Assigns own enumerable properties of source object(s) to the destination
  664. * object. Subsequent sources will overwrite propery assignments of previous
  665. * sources. If a `callback` function is passed, it will be executed to produce
  666. * the assigned values. The `callback` is bound to `thisArg` and invoked with
  667. * two arguments; (objectValue, sourceValue).
  668. *
  669. * @static
  670. * @memberOf _
  671. * @type Function
  672. * @alias extend
  673. * @category Objects
  674. * @param {Object} object The destination object.
  675. * @param {Object} [source1, source2, ...] The source objects.
  676. * @param {Function} [callback] The function to customize assigning values.
  677. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  678. * @returns {Object} Returns the destination object.
  679. * @example
  680. *
  681. * _.assign({ 'name': 'moe' }, { 'age': 40 });
  682. * // => { 'name': 'moe', 'age': 40 }
  683. *
  684. * var defaults = _.partialRight(_.assign, function(a, b) {
  685. * return typeof a == 'undefined' ? b : a;
  686. * });
  687. *
  688. * var food = { 'name': 'apple' };
  689. * defaults(food, { 'name': 'banana', 'type': 'fruit' });
  690. * // => { 'name': 'apple', 'type': 'fruit' }
  691. */
  692. function assign(object) {
  693. if (!object) {
  694. return object;
  695. }
  696. for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
  697. var iterable = arguments[argsIndex];
  698. if (iterable) {
  699. for (var key in iterable) {
  700. object[key] = iterable[key];
  701. }
  702. }
  703. }
  704. return object;
  705. }
  706. /**
  707. * Creates a clone of `value`. If `deep` is `true`, nested objects will also
  708. * be cloned, otherwise they will be assigned by reference. If a `callback`
  709. * function is passed, it will be executed to produce the cloned values. If
  710. * `callback` returns `undefined`, cloning will be handled by the method instead.
  711. * The `callback` is bound to `thisArg` and invoked with one argument; (value).
  712. *
  713. * @static
  714. * @memberOf _
  715. * @category Objects
  716. * @param {Mixed} value The value to clone.
  717. * @param {Boolean} [deep=false] A flag to indicate a deep clone.
  718. * @param {Function} [callback] The function to customize cloning values.
  719. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  720. * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
  721. * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
  722. * @returns {Mixed} Returns the cloned `value`.
  723. * @example
  724. *
  725. * var stooges = [
  726. * { 'name': 'moe', 'age': 40 },
  727. * { 'name': 'larry', 'age': 50 }
  728. * ];
  729. *
  730. * var shallow = _.clone(stooges);
  731. * shallow[0] === stooges[0];
  732. * // => true
  733. *
  734. * var deep = _.clone(stooges, true);
  735. * deep[0] === stooges[0];
  736. * // => false
  737. *
  738. * _.mixin({
  739. * 'clone': _.partialRight(_.clone, function(value) {
  740. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  741. * })
  742. * });
  743. *
  744. * var clone = _.clone(document.body);
  745. * clone.childNodes.length;
  746. * // => 0
  747. */
  748. function clone(value) {
  749. return isObject(value)
  750. ? (isArray(value) ? slice(value) : assign({}, value))
  751. : value
  752. }
  753. /**
  754. * Assigns own enumerable properties of source object(s) to the destination
  755. * object for all destination properties that resolve to `undefined`. Once a
  756. * property is set, additional defaults of the same property will be ignored.
  757. *
  758. * @static
  759. * @memberOf _
  760. * @type Function
  761. * @category Objects
  762. * @param {Object} object The destination object.
  763. * @param {Object} [source1, source2, ...] The source objects.
  764. * @param- {Object} [guard] Internally used to allow working with `_.reduce`
  765. * without using its callback's `key` and `object` arguments as sources.
  766. * @returns {Object} Returns the destination object.
  767. * @example
  768. *
  769. * var food = { 'name': 'apple' };
  770. * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
  771. * // => { 'name': 'apple', 'type': 'fruit' }
  772. */
  773. function defaults(object) {
  774. if (!object) {
  775. return object;
  776. }
  777. for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
  778. var iterable = arguments[argsIndex];
  779. if (iterable) {
  780. for (var key in iterable) {
  781. if (object[key] == null) {
  782. object[key] = iterable[key];
  783. }
  784. }
  785. }
  786. }
  787. return object;
  788. }
  789. /**
  790. * Creates a sorted array of all enumerable properties, own and inherited,
  791. * of `object` that have function values.
  792. *
  793. * @static
  794. * @memberOf _
  795. * @alias methods
  796. * @category Objects
  797. * @param {Object} object The object to inspect.
  798. * @returns {Array} Returns a new array of property names that have function values.
  799. * @example
  800. *
  801. * _.functions(_);
  802. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  803. */
  804. function functions(object) {
  805. var result = [];
  806. forIn(object, function(value, key) {
  807. if (isFunction(value)) {
  808. result.push(key);
  809. }
  810. });
  811. return result.sort();
  812. }
  813. /**
  814. * Checks if the specified object `property` exists and is a direct property,
  815. * instead of an inherited property.
  816. *
  817. * @static
  818. * @memberOf _
  819. * @category Objects
  820. * @param {Object} object The object to check.
  821. * @param {String} property The property to check for.
  822. * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
  823. * @example
  824. *
  825. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  826. * // => true
  827. */
  828. function has(object, property) {
  829. return object ? hasOwnProperty.call(object, property) : false;
  830. }
  831. /**
  832. * Creates an object composed of the inverted keys and values of the given `object`.
  833. *
  834. * @static
  835. * @memberOf _
  836. * @category Objects
  837. * @param {Object} object The object to invert.
  838. * @returns {Object} Returns the created inverted object.
  839. * @example
  840. *
  841. * _.invert({ 'first': 'moe', 'second': 'larry' });
  842. * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
  843. */
  844. function invert(object) {
  845. var index = -1,
  846. props = keys(object),
  847. length = props.length,
  848. result = {};
  849. while (++index < length) {
  850. var key = props[index];
  851. result[object[key]] = key;
  852. }
  853. return result;
  854. }
  855. /**
  856. * Checks if `value` is a boolean value.
  857. *
  858. * @static
  859. * @memberOf _
  860. * @category Objects
  861. * @param {Mixed} value The value to check.
  862. * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
  863. * @example
  864. *
  865. * _.isBoolean(null);
  866. * // => false
  867. */
  868. function isBoolean(value) {
  869. return value === true || value === false || toString.call(value) == boolClass;
  870. }
  871. /**
  872. * Checks if `value` is a date.
  873. *
  874. * @static
  875. * @memberOf _
  876. * @category Objects
  877. * @param {Mixed} value The value to check.
  878. * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
  879. * @example
  880. *
  881. * _.isDate(new Date);
  882. * // => true
  883. */
  884. function isDate(value) {
  885. return value instanceof Date || toString.call(value) == dateClass;
  886. }
  887. /**
  888. * Checks if `value` is a DOM element.
  889. *
  890. * @static
  891. * @memberOf _
  892. * @category Objects
  893. * @param {Mixed} value The value to check.
  894. * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
  895. * @example
  896. *
  897. * _.isElement(document.body);
  898. * // => true
  899. */
  900. function isElement(value) {
  901. return value ? value.nodeType === 1 : false;
  902. }
  903. /**
  904. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  905. * length of `0` and objects with no own enumerable properties are considered
  906. * "empty".
  907. *
  908. * @static
  909. * @memberOf _
  910. * @category Objects
  911. * @param {Array|Object|String} value The value to inspect.
  912. * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
  913. * @example
  914. *
  915. * _.isEmpty([1, 2, 3]);
  916. * // => false
  917. *
  918. * _.isEmpty({});
  919. * // => true
  920. *
  921. * _.isEmpty('');
  922. * // => true
  923. */
  924. function isEmpty(value) {
  925. if (!value) {
  926. return true;
  927. }
  928. if (isArray(value) || isString(value)) {
  929. return !value.length;
  930. }
  931. for (var key in value) {
  932. if (hasOwnProperty.call(value, key)) {
  933. return false;
  934. }
  935. }
  936. return true;
  937. }
  938. /**
  939. * Performs a deep comparison between two values to determine if they are
  940. * equivalent to each other. If `callback` is passed, it will be executed to
  941. * compare values. If `callback` returns `undefined`, comparisons will be handled
  942. * by the method instead. The `callback` is bound to `thisArg` and invoked with
  943. * two arguments; (a, b).
  944. *
  945. * @static
  946. * @memberOf _
  947. * @category Objects
  948. * @param {Mixed} a The value to compare.
  949. * @param {Mixed} b The other value to compare.
  950. * @param {Function} [callback] The function to customize comparing values.
  951. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  952. * @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
  953. * @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
  954. * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
  955. * @example
  956. *
  957. * var moe = { 'name': 'moe', 'age': 40 };
  958. * var copy = { 'name': 'moe', 'age': 40 };
  959. *
  960. * moe == copy;
  961. * // => false
  962. *
  963. * _.isEqual(moe, copy);
  964. * // => true
  965. *
  966. * var words = ['hello', 'goodbye'];
  967. * var otherWords = ['hi', 'goodbye'];
  968. *
  969. * _.isEqual(words, otherWords, function(a, b) {
  970. * var reGreet = /^(?:hello|hi)$/i,
  971. * aGreet = _.isString(a) && reGreet.test(a),
  972. * bGreet = _.isString(b) && reGreet.test(b);
  973. *
  974. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  975. * });
  976. * // => true
  977. */
  978. function isEqual(a, b, stackA, stackB) {
  979. if (a === b) {
  980. return a !== 0 || (1 / a == 1 / b);
  981. }
  982. var type = typeof a,
  983. otherType = typeof b;
  984. if (a === a &&
  985. (!a || (type != 'function' && type != 'object')) &&
  986. (!b || (otherType != 'function' && otherType != 'object'))) {
  987. return false;
  988. }
  989. if (a == null || b == null) {
  990. return a === b;
  991. }
  992. var className = toString.call(a),
  993. otherClass = toString.call(b);
  994. if (className != otherClass) {
  995. return false;
  996. }
  997. switch (className) {
  998. case boolClass:
  999. case dateClass:
  1000. return +a == +b;
  1001. case numberClass:
  1002. return a != +a
  1003. ? b != +b
  1004. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  1005. case regexpClass:
  1006. case stringClass:
  1007. return a == b + '';
  1008. }
  1009. var isArr = className == arrayClass;
  1010. if (!isArr) {
  1011. if (a.__wrapped__ || b.__wrapped__) {
  1012. return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, stackA, stackB);
  1013. }
  1014. if (className != objectClass) {
  1015. return false;
  1016. }
  1017. var ctorA = a.constructor,
  1018. ctorB = b.constructor;
  1019. if (ctorA != ctorB && !(
  1020. isFunction(ctorA) && ctorA instanceof ctorA &&
  1021. isFunction(ctorB) && ctorB instanceof ctorB
  1022. )) {
  1023. return false;
  1024. }
  1025. }
  1026. stackA || (stackA = []);
  1027. stackB || (stackB = []);
  1028. var length = stackA.length;
  1029. while (length--) {
  1030. if (stackA[length] == a) {
  1031. return stackB[length] == b;
  1032. }
  1033. }
  1034. var result = true,
  1035. size = 0;
  1036. stackA.push(a);
  1037. stackB.push(b);
  1038. if (isArr) {
  1039. size = b.length;
  1040. result = size == a.length;
  1041. if (result) {
  1042. while (size--) {
  1043. if (!(result = isEqual(a[size], b[size], stackA, stackB))) {
  1044. break;
  1045. }
  1046. }
  1047. }
  1048. return result;
  1049. }
  1050. forIn(b, function(value, key, b) {
  1051. if (hasOwnProperty.call(b, key)) {
  1052. size++;
  1053. return !(result = hasOwnProperty.call(a, key) && isEqual(a[key], value, stackA, stackB)) && indicatorObject;
  1054. }
  1055. });
  1056. if (result) {
  1057. forIn(a, function(value, key, a) {
  1058. if (hasOwnProperty.call(a, key)) {
  1059. return !(result = --size > -1) && indicatorObject;
  1060. }
  1061. });
  1062. }
  1063. return result;
  1064. }
  1065. /**
  1066. * Checks if `value` is, or can be coerced to, a finite number.
  1067. *
  1068. * Note: This is not the same as native `isFinite`, which will return true for
  1069. * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
  1070. *
  1071. * @static
  1072. * @memberOf _
  1073. * @category Objects
  1074. * @param {Mixed} value The value to check.
  1075. * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
  1076. * @example
  1077. *
  1078. * _.isFinite(-101);
  1079. * // => true
  1080. *
  1081. * _.isFinite('10');
  1082. * // => true
  1083. *
  1084. * _.isFinite(true);
  1085. * // => false
  1086. *
  1087. * _.isFinite('');
  1088. * // => false
  1089. *
  1090. * _.isFinite(Infinity);
  1091. * // => false
  1092. */
  1093. function isFinite(value) {
  1094. return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
  1095. }
  1096. /**
  1097. * Checks if `value` is a function.
  1098. *
  1099. * @static
  1100. * @memberOf _
  1101. * @category Objects
  1102. * @param {Mixed} value The value to check.
  1103. * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
  1104. * @example
  1105. *
  1106. * _.isFunction(_);
  1107. * // => true
  1108. */
  1109. function isFunction(value) {
  1110. return typeof value == 'function';
  1111. }
  1112. // fallback for older versions of Chrome and Safari
  1113. if (isFunction(/x/)) {
  1114. isFunction = function(value) {
  1115. return value instanceof Function || toString.call(value) == funcClass;
  1116. };
  1117. }
  1118. /**
  1119. * Checks if `value` is the language type of Object.
  1120. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  1121. *
  1122. * @static
  1123. * @memberOf _
  1124. * @category Objects
  1125. * @param {Mixed} value The value to check.
  1126. * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
  1127. * @example
  1128. *
  1129. * _.isObject({});
  1130. * // => true
  1131. *
  1132. * _.isObject([1, 2, 3]);
  1133. * // => true
  1134. *
  1135. * _.isObject(1);
  1136. * // => false
  1137. */
  1138. function isObject(value) {
  1139. // check if the value is the ECMAScript language type of Object
  1140. // http://es5.github.com/#x8
  1141. // and avoid a V8 bug
  1142. // http://code.google.com/p/v8/issues/detail?id=2291
  1143. return value ? objectTypes[typeof value] : false;
  1144. }
  1145. /**
  1146. * Checks if `value` is `NaN`.
  1147. *
  1148. * Note: This is not the same as native `isNaN`, which will return `true` for
  1149. * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
  1150. *
  1151. * @static
  1152. * @memberOf _
  1153. * @category Objects
  1154. * @param {Mixed} value The value to check.
  1155. * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
  1156. * @example
  1157. *
  1158. * _.isNaN(NaN);
  1159. * // => true
  1160. *
  1161. * _.isNaN(new Number(NaN));
  1162. * // => true
  1163. *
  1164. * isNaN(undefined);
  1165. * // => true
  1166. *
  1167. * _.isNaN(undefined);
  1168. * // => false
  1169. */
  1170. function isNaN(value) {
  1171. // `NaN` as a primitive is the only value that is not equal to itself
  1172. // (perform the [[Class]] check first to avoid errors with some host objects in IE)
  1173. return isNumber(value) && value != +value
  1174. }
  1175. /**
  1176. * Checks if `value` is `null`.
  1177. *
  1178. * @static
  1179. * @memberOf _
  1180. * @category Objects
  1181. * @param {Mixed} value The value to check.
  1182. * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
  1183. * @example
  1184. *
  1185. * _.isNull(null);
  1186. * // => true
  1187. *
  1188. * _.isNull(undefined);
  1189. * // => false
  1190. */
  1191. function isNull(value) {
  1192. return value === null;
  1193. }
  1194. /**
  1195. * Checks if `value` is a number.
  1196. *
  1197. * @static
  1198. * @memberOf _
  1199. * @category Objects
  1200. * @param {Mixed} value The value to check.
  1201. * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
  1202. * @example
  1203. *
  1204. * _.isNumber(8.4 * 5);
  1205. * // => true
  1206. */
  1207. function isNumber(value) {
  1208. return typeof value == 'number' || toString.call(value) == numberClass;
  1209. }
  1210. /**
  1211. * Checks if `value` is a regular expression.
  1212. *
  1213. * @static
  1214. * @memberOf _
  1215. * @category Objects
  1216. * @param {Mixed} value The value to check.
  1217. * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
  1218. * @example
  1219. *
  1220. * _.isRegExp(/moe/);
  1221. * // => true
  1222. */
  1223. function isRegExp(value) {
  1224. return value instanceof RegExp || toString.call(value) == regexpClass;
  1225. }
  1226. /**
  1227. * Checks if `value` is a string.
  1228. *
  1229. * @static
  1230. * @memberOf _
  1231. * @category Objects
  1232. * @param {Mixed} value The value to check.
  1233. * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
  1234. * @example
  1235. *
  1236. * _.isString('moe');
  1237. * // => true
  1238. */
  1239. function isString(value) {
  1240. return typeof value == 'string' || toString.call(value) == stringClass;
  1241. }
  1242. /**
  1243. * Checks if `value` is `undefined`.
  1244. *
  1245. * @static
  1246. * @memberOf _
  1247. * @category Objects
  1248. * @param {Mixed} value The value to check.
  1249. * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
  1250. * @example
  1251. *
  1252. * _.isUndefined(void 0);
  1253. * // => true
  1254. */
  1255. function isUndefined(value) {
  1256. return typeof value == 'undefined';
  1257. }
  1258. /**
  1259. * Creates a shallow clone of `object` excluding the specified properties.
  1260. * Property names may be specified as individual arguments or as arrays of
  1261. * property names. If a `callback` function is passed, it will be executed
  1262. * for each property in the `object`, omitting the properties `callback`
  1263. * returns truthy for. The `callback` is bound to `thisArg` and invoked
  1264. * with three arguments; (value, key, object).
  1265. *
  1266. * @static
  1267. * @memberOf _
  1268. * @category Objects
  1269. * @param {Object} object The source object.
  1270. * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
  1271. * or the function called per iteration.
  1272. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1273. * @returns {Object} Returns an object without the omitted properties.
  1274. * @example
  1275. *
  1276. * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
  1277. * // => { 'name': 'moe' }
  1278. *
  1279. * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
  1280. * return typeof value == 'number';
  1281. * });
  1282. * // => { 'name': 'moe' }
  1283. */
  1284. function omit(object) {
  1285. var props = concat.apply(arrayRef, arguments),
  1286. result = {};
  1287. forIn(object, function(value, key) {
  1288. if (indexOf(props, key, 1) < 0) {
  1289. result[key] = value;
  1290. }
  1291. });
  1292. return result;
  1293. }
  1294. /**
  1295. * Creates a two dimensional array of the given object's key-value pairs,
  1296. * i.e. `[[key1, value1], [key2, value2]]`.
  1297. *
  1298. * @static
  1299. * @memberOf _
  1300. * @category Objects
  1301. * @param {Object} object The object to inspect.
  1302. * @returns {Array} Returns new array of key-value pairs.
  1303. * @example
  1304. *
  1305. * _.pairs({ 'moe': 30, 'larry': 40 });
  1306. * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
  1307. */
  1308. function pairs(object) {
  1309. var index = -1,
  1310. props = keys(object),
  1311. length = props.length,
  1312. result = Array(length);
  1313. while (++index < length) {
  1314. var key = props[index];
  1315. result[index] = [key, object[key]];
  1316. }
  1317. return result;
  1318. }
  1319. /**
  1320. * Creates a shallow clone of `object` composed of the specified properties.
  1321. * Property names may be specified as individual arguments or as arrays of property
  1322. * names. If `callback` is passed, it will be executed for each property in the
  1323. * `object`, picking the properties `callback` returns truthy for. The `callback`
  1324. * is bound to `thisArg` and invoked with three arguments; (value, key, object).
  1325. *
  1326. * @static
  1327. * @memberOf _
  1328. * @category Objects
  1329. * @param {Object} object The source object.
  1330. * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
  1331. * per iteration or properties to pick, either as individual arguments or arrays.
  1332. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1333. * @returns {Object} Returns an object composed of the picked properties.
  1334. * @example
  1335. *
  1336. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
  1337. * // => { 'name': 'moe' }
  1338. *
  1339. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
  1340. * return key.charAt(0) != '_';
  1341. * });
  1342. * // => { 'name': 'moe' }
  1343. */
  1344. function pick(object) {
  1345. var index = 0,
  1346. props = concat.apply(arrayRef, arguments),
  1347. length = props.length,
  1348. result = {};
  1349. while (++index < length) {
  1350. var prop = props[index];
  1351. if (prop in object) {
  1352. result[prop] = object[prop];
  1353. }
  1354. }
  1355. return result;
  1356. }
  1357. /**
  1358. * Creates an array composed of the own enumerable property values of `object`.
  1359. *
  1360. * @static
  1361. * @memberOf _
  1362. * @category Objects
  1363. * @param {Object} object The object to inspect.
  1364. * @returns {Array} Returns a new array of property values.
  1365. * @example
  1366. *
  1367. * _.values({ 'one': 1, 'two': 2, 'three': 3 });
  1368. * // => [1, 2, 3]
  1369. */
  1370. function values(object) {
  1371. var index = -1,
  1372. props = keys(object),
  1373. length = props.length,
  1374. result = Array(length);
  1375. while (++index < length) {
  1376. result[index] = object[props[index]];
  1377. }
  1378. return result;
  1379. }
  1380. /*--------------------------------------------------------------------------*/
  1381. /**
  1382. * Checks if a given `target` element is present in a `collection` using strict
  1383. * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
  1384. * as the offset from the end of the collection.
  1385. *
  1386. * @static
  1387. * @memberOf _
  1388. * @alias include
  1389. * @category Collections
  1390. * @param {Array|Object|String} collection The collection to iterate over.
  1391. * @param {Mixed} target The value to check for.
  1392. * @param {Number} [fromIndex=0] The index to search from.
  1393. * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
  1394. * @example
  1395. *
  1396. * _.contains([1, 2, 3], 1);
  1397. * // => true
  1398. *
  1399. * _.contains([1, 2, 3], 1, 2);
  1400. * // => false
  1401. *
  1402. * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
  1403. * // => true
  1404. *
  1405. * _.contains('curly', 'ur');
  1406. * // => true
  1407. */
  1408. function contains(collection, target) {
  1409. var length = collection ? collection.length : 0,
  1410. result = false;
  1411. if (typeof length == 'number') {
  1412. result = indexOf(collection, target) > -1;
  1413. } else {
  1414. each(collection, function(value) {
  1415. return (result = value === target) && indicatorObject;
  1416. });
  1417. }
  1418. return result;
  1419. }
  1420. /**
  1421. * Creates an object composed of keys returned from running each element of the
  1422. * `collection` through the given `callback`. The corresponding value of each key
  1423. * is the number of times the key was returned by the `callback`. The `callback`
  1424. * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
  1425. *
  1426. * If a property name is passed for `callback`, the created "_.pluck" style
  1427. * callback will return the property value of the given element.
  1428. *
  1429. * If an object is passed for `callback`, the created "_.where" style callback
  1430. * will return `true` for elements that have the propeties of the given object,
  1431. * else `false`.
  1432. *
  1433. * @static
  1434. * @memberOf _
  1435. * @category Collections
  1436. * @param {Array|Object|String} collection The collection to iterate over.
  1437. * @param {Function|Object|String} [callback=identity] The function called per
  1438. * iteration. If a property name or object is passed, it will be used to create
  1439. * a "_.pluck" or "_.where" style callback, respectively.
  1440. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1441. * @returns {Object} Returns the composed aggregate object.
  1442. * @example
  1443. *
  1444. * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
  1445. * // => { '4': 1, '6': 2 }
  1446. *
  1447. * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  1448. * // => { '4': 1, '6': 2 }
  1449. *
  1450. * _.countBy(['one', 'two', 'three'], 'length');
  1451. * // => { '3': 2, '5': 1 }
  1452. */
  1453. function countBy(collection, callback, thisArg) {
  1454. var result = {};
  1455. callback = createCallback(callback, thisArg);
  1456. forEach(collection, function(value, key, collection) {
  1457. key = callback(value, key, collection) + '';
  1458. (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
  1459. });
  1460. return result;
  1461. }
  1462. /**
  1463. * Checks if the `callback` returns a truthy value for **all** elements of a
  1464. * `collection`. The `callback` is bound to `thisArg` and invoked with three
  1465. * arguments; (value, index|key, collection).
  1466. *
  1467. * If a property name is passed for `callback`, the created "_.pluck" style
  1468. * callback will return the property value of the given element.
  1469. *
  1470. * If an object is passed for `callback`, the created "_.where" style callback
  1471. * will return `true` for elements that have the propeties of the given object,
  1472. * else `false`.
  1473. *
  1474. * @static
  1475. * @memberOf _
  1476. * @alias all
  1477. * @category Collections
  1478. * @param {Array|Object|String} collection The collection to iterate over.
  1479. * @param {Function|Object|String} [callback=identity] The function called per
  1480. * iteration. If a property name or object is passed, it will be used to create
  1481. * a "_.pluck" or "_.where" style callback, respectively.
  1482. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1483. * @returns {Boolean} Returns `true` if all elements pass the callback check,
  1484. * else `false`.
  1485. * @example
  1486. *
  1487. * _.every([true, 1, null, 'yes'], Boolean);
  1488. * // => false
  1489. *
  1490. * var stooges = [
  1491. * { 'name': 'moe', 'age': 40 },
  1492. * { 'name': 'larry', 'age': 50 }
  1493. * ];
  1494. *
  1495. * // using "_.pluck" callback shorthand
  1496. * _.every(stooges, 'age');
  1497. * // => true
  1498. *
  1499. * // using "_.where" callback shorthand
  1500. * _.every(stooges, { 'age': 50 });
  1501. * // => false
  1502. */
  1503. function every(collection, callback, thisArg) {
  1504. var result = true;
  1505. callback = createCallback(callback, thisArg);
  1506. if (isArray(collection)) {
  1507. var index = -1,
  1508. length = collection.length;
  1509. while (++index < length) {
  1510. if (!(result = !!callback(collection[index], index, collection))) {
  1511. break;
  1512. }
  1513. }
  1514. } else {
  1515. each(collection, function(value, index, collection) {
  1516. return !(result = !!callback(value, index, collection)) && indicatorObject;
  1517. });
  1518. }
  1519. return result;
  1520. }
  1521. /**
  1522. * Examines each element in a `collection`, returning an array of all elements
  1523. * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
  1524. * invoked with three arguments; (value, index|key, collection).
  1525. *
  1526. * If a property name is passed for `callback`, the created "_.pluck" style
  1527. * callback will return the property value of the given element.
  1528. *
  1529. * If an object is passed for `callback`, the created "_.where" style callback
  1530. * will return `true` for elements that have the propeties of the given object,
  1531. * else `false`.
  1532. *
  1533. * @static
  1534. * @memberOf _
  1535. * @alias select
  1536. * @category Collections
  1537. * @param {Array|Object|String} collection The collection to iterate over.
  1538. * @param {Function|Object|String} [callback=identity] The function called per
  1539. * iteration. If a property name or object is passed, it will be used to create
  1540. * a "_.pluck" or "_.where" style callback, respectively.
  1541. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1542. * @returns {Array} Returns a new array of elements that passed the callback check.
  1543. * @example
  1544. *
  1545. * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  1546. * // => [2, 4, 6]
  1547. *
  1548. * var food = [
  1549. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  1550. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  1551. * ];
  1552. *
  1553. * // using "_.pluck" callback shorthand
  1554. * _.filter(food, 'organic');
  1555. * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
  1556. *
  1557. * // using "_.where" callback shorthand
  1558. * _.filter(food, { 'type': 'fruit' });
  1559. * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
  1560. */
  1561. function filter(collection, callback, thisArg) {
  1562. var result = [];
  1563. callback = createCallback(callback, thisArg);
  1564. if (isArray(collection)) {
  1565. var index = -1,
  1566. length = collection.length;
  1567. while (++index < length) {
  1568. var value = collection[index];
  1569. if (callback(value, index, collection)) {
  1570. result.push(value);
  1571. }
  1572. }
  1573. } else {
  1574. each(collection, function(value, index, collection) {
  1575. if (callback(value, index, collection)) {
  1576. result.push(value);
  1577. }
  1578. });
  1579. }
  1580. return result;
  1581. }
  1582. /**
  1583. * Examines each element in a `collection`, returning the first that the `callback`
  1584. * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
  1585. * arguments; (value, index|key, collection).
  1586. *
  1587. * If a property name is passed for `callback`, the created "_.pluck" style
  1588. * callback will return the property value of the given element.
  1589. *
  1590. * If an object is passed for `callback`, the created "_.where" style callback
  1591. * will return `true` for elements that have the propeties of the given object,
  1592. * else `false`.
  1593. *
  1594. * @static
  1595. * @memberOf _
  1596. * @alias detect
  1597. * @category Collections
  1598. * @param {Array|Object|String} collection The collection to iterate over.
  1599. * @param {Function|Object|String} [callback=identity] The function called per
  1600. * iteration. If a property name or object is passed, it will be used to create
  1601. * a "_.pluck" or "_.where" style callback, respectively.
  1602. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1603. * @returns {Mixed} Returns the element that passed the callback check,
  1604. * else `undefined`.
  1605. * @example
  1606. *
  1607. * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  1608. * // => 2
  1609. *
  1610. * var food = [
  1611. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  1612. * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
  1613. * { 'name': 'beet', 'organic': false, 'type': 'vegetable' },
  1614. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  1615. * ];
  1616. *
  1617. * // using "_.where" callback shorthand
  1618. * var veggie = _.find(food, { 'type': 'vegetable' });
  1619. * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
  1620. *
  1621. * // using "_.pluck" callback shorthand
  1622. * var healthy = _.find(food, 'organic');
  1623. * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
  1624. */
  1625. function find(collection, callback, thisArg) {
  1626. var result;
  1627. callback = createCallback(callback, thisArg);
  1628. forEach(collection, function(value, index, collection) {
  1629. if (callback(value, index, collection)) {
  1630. result = value;
  1631. return indicatorObject;
  1632. }
  1633. });
  1634. return result;
  1635. }
  1636. function findWhere(object, properties) {
  1637. return where(object, properties, true);
  1638. }
  1639. /**
  1640. * Iterates over a `collection`, executing the `callback` for each element in
  1641. * the `collection`. The `callback` is bound to `thisArg` and invoked with three
  1642. * arguments; (value, index|key, collection). Callbacks may exit iteration early
  1643. * by explicitly returning `false`.
  1644. *
  1645. * @static
  1646. * @memberOf _
  1647. * @alias each
  1648. * @category Collections
  1649. * @param {Array|Object|String} collection The collection to iterate over.
  1650. * @param {Function} [callback=identity] The function called per iteration.
  1651. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1652. * @returns {Array|Object|String} Returns `collection`.
  1653. * @example
  1654. *
  1655. * _([1, 2, 3]).forEach(alert).join(',');
  1656. * // => alerts each number and returns '1,2,3'
  1657. *
  1658. * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
  1659. * // => alerts each number value (order is not guaranteed)
  1660. */
  1661. function forEach(collection, callback, thisArg) {
  1662. if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
  1663. var index = -1,
  1664. length = collection.length;
  1665. while (++index < length) {
  1666. if (callback(collection[index], index, collection) === indicatorObject) {
  1667. break;
  1668. }
  1669. }
  1670. } else {
  1671. each(collection, callback, thisArg);
  1672. };
  1673. }
  1674. /**
  1675. * Creates an object composed of keys returned from running each element of the
  1676. * `collection` through the `callback`. The corresponding value of each key is
  1677. * an array of elements passed to `callback` that returned the key. The `callback`
  1678. * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
  1679. *
  1680. * If a property name is passed for `callback`, the created "_.pluck" style
  1681. * callback will return the property value of the given element.
  1682. *
  1683. * If an object is passed for `callback`, the created "_.where" style callback
  1684. * will return `true` for elements that have the propeties of the given object,
  1685. * else `false`
  1686. *
  1687. * @static
  1688. * @memberOf _
  1689. * @category Collections
  1690. * @param {Array|Object|String} collection The collection to iterate over.
  1691. * @param {Function|Object|String} [callback=identity] The function called per
  1692. * iteration. If a property name or object is passed, it will be used to create
  1693. * a "_.pluck" or "_.where" style callback, respectively.
  1694. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1695. * @returns {Object} Returns the composed aggregate object.
  1696. * @example
  1697. *
  1698. * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
  1699. * // => { '4': [4.2], '6': [6.1, 6.4] }
  1700. *
  1701. * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  1702. * // => { '4': [4.2], '6': [6.1, 6.4] }
  1703. *
  1704. * // using "_.pluck" callback shorthand
  1705. * _.groupBy(['one', 'two', 'three'], 'length');
  1706. * // => { '3': ['one', 'two'], '5': ['three'] }
  1707. */
  1708. function groupBy(collection, callback, thisArg) {
  1709. var result = {};
  1710. callback = createCallback(callback, thisArg);
  1711. forEach(collection, function(value, key, collection) {
  1712. key = callback(value, key, collection) + '';
  1713. (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
  1714. });
  1715. return result;
  1716. }
  1717. /**
  1718. * Invokes the method named by `methodName` on each element in the `collection`,
  1719. * returning an array of the results of each invoked method. Additional arguments
  1720. * will be passed to each invoked method. If `methodName` is a function, it will
  1721. * be invoked for, and `this` bound to, each element in the `collection`.
  1722. *
  1723. * @static
  1724. * @memberOf _
  1725. * @category Collections
  1726. * @param {Array|Object|String} collection The collection to iterate over.
  1727. * @param {Function|String} methodName The name of the method to invoke or
  1728. * the function invoked per iteration.
  1729. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
  1730. * @returns {Array} Returns a new array of the results of each invoked method.
  1731. * @example
  1732. *
  1733. * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
  1734. * // => [[1, 5, 7], [1, 2, 3]]
  1735. *
  1736. * _.invoke([123, 456], String.prototype.split, '');
  1737. * // => [['1', '2', '3'], ['4', '5', '6']]
  1738. */
  1739. function invoke(collection, methodName) {
  1740. var args = slice(arguments, 2),
  1741. index = -1,
  1742. isFunc = typeof methodName == 'function',
  1743. length = collection ? collection.length : 0,
  1744. result = Array(typeof length == 'number' ? length : 0);
  1745. forEach(collection, function(value) {
  1746. result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
  1747. });
  1748. return result;
  1749. }
  1750. /**
  1751. * Creates an array of values by running each element in the `collection`
  1752. * through the `callback`. The `callback` is bound to `thisArg` and invoked with
  1753. * three arguments; (value, index|key, collection).
  1754. *
  1755. * If a property name is passed for `callback`, the created "_.pluck" style
  1756. * callback will return the property value of the given element.
  1757. *
  1758. * If an object is passed for `callback`, the created "_.where" style callback
  1759. * will return `true` for elements that have the propeties of the given object,
  1760. * else `false`.
  1761. *
  1762. * @static
  1763. * @memberOf _
  1764. * @alias collect
  1765. * @category Collections
  1766. * @param {Array|Object|String} collection The collection to iterate over.
  1767. * @param {Function|Object|String} [callback=identity] The function called per
  1768. * iteration. If a property name or object is passed, it will be used to create
  1769. * a "_.pluck" or "_.where" style callback, respectively.
  1770. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1771. * @returns {Array} Returns a new array of the results of each `callback` execution.
  1772. * @example
  1773. *
  1774. * _.map([1, 2, 3], function(num) { return num * 3; });
  1775. * // => [3, 6, 9]
  1776. *
  1777. * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
  1778. * // => [3, 6, 9] (order is not guaranteed)
  1779. *
  1780. * var stooges = [
  1781. * { 'name': 'moe', 'age': 40 },
  1782. * { 'name': 'larry', 'age': 50 }
  1783. * ];
  1784. *
  1785. * // using "_.pluck" callback shorthand
  1786. * _.map(stooges, 'name');
  1787. * // => ['moe', 'larry']
  1788. */
  1789. function map(collection, callback, thisArg) {
  1790. var index = -1,
  1791. length = collection ? collection.length : 0,
  1792. result = Array(typeof length == 'number' ? length : 0);
  1793. callback = createCallback(callback, thisArg);
  1794. if (isArray(collection)) {
  1795. while (++index < length) {
  1796. result[index] = callback(collection[index], index, collection);
  1797. }
  1798. } else {
  1799. each(collection, function(value, key, collection) {
  1800. result[++index] = callback(value, key, collection);
  1801. });
  1802. }
  1803. return result;
  1804. }
  1805. /**
  1806. * Retrieves the maximum value of an `array`. If `callback` is passed,
  1807. * it will be executed for each value in the `array` to generate the
  1808. * criterion by which the value is ranked. The `callback` is bound to
  1809. * `thisArg` and invoked with three arguments; (value, index, collection).
  1810. *
  1811. * If a property name is passed for `callback`, the created "_.pluck" style
  1812. * callback will return the property value of the given element.
  1813. *
  1814. * If an object is passed for `callback`, the created "_.where" style callback
  1815. * will return `true` for elements that have the propeties of the given object,
  1816. * else `false`.
  1817. *
  1818. * @static
  1819. * @memberOf _
  1820. * @category Collections
  1821. * @param {Array|Object|String} collection The collection to iterate over.
  1822. * @param {Function|Object|String} [callback=identity] The function called per
  1823. * iteration. If a property name or object is passed, it will be used to create
  1824. * a "_.pluck" or "_.where" style callback, respectively.
  1825. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1826. * @returns {Mixed} Returns the maximum value.
  1827. * @example
  1828. *
  1829. * _.max([4, 2, 8, 6]);
  1830. * // => 8
  1831. *
  1832. * var stooges = [
  1833. * { 'name': 'moe', 'age': 40 },
  1834. * { 'name': 'larry', 'age': 50 }
  1835. * ];
  1836. *
  1837. * _.max(stooges, function(stooge) { return stooge.age; });
  1838. * // => { 'name': 'larry', 'age': 50 };
  1839. *
  1840. * // using "_.pluck" callback shorthand
  1841. * _.max(stooges, 'age');
  1842. * // => { 'name': 'larry', 'age': 50 };
  1843. */
  1844. function max(collection, callback, thisArg) {
  1845. var computed = -Infinity,
  1846. result = computed;
  1847. if (!callback && isArray(collection)) {
  1848. var index = -1,
  1849. length = collection.length;
  1850. while (++index < length) {
  1851. var value = collection[index];
  1852. if (value > result) {
  1853. result = value;
  1854. }
  1855. }
  1856. } else {
  1857. callback = createCallback(callback, thisArg);
  1858. each(collection, function(value, index, collection) {
  1859. var current = callback(value, index, collection);
  1860. if (current > computed) {
  1861. computed = current;
  1862. result = value;
  1863. }
  1864. });
  1865. }
  1866. return result;
  1867. }
  1868. /**
  1869. * Retrieves the minimum value of an `array`. If `callback` is passed,
  1870. * it will be executed for each value in the `array` to generate the
  1871. * criterion by which the value is ranked. The `callback` is bound to `thisArg`
  1872. * and invoked with three arguments; (value, index, collection).
  1873. *
  1874. * If a property name is passed for `callback`, the created "_.pluck" style
  1875. * callback will return the property value of the given element.
  1876. *
  1877. * If an object is passed for `callback`, the created "_.where" style callback
  1878. * will return `true` for elements that have the propeties of the given object,
  1879. * else `false`.
  1880. *
  1881. * @static
  1882. * @memberOf _
  1883. * @category Collections
  1884. * @param {Array|Object|String} collection The collection to iterate over.
  1885. * @param {Function|Object|String} [callback=identity] The function called per
  1886. * iteration. If a property name or object is passed, it will be used to create
  1887. * a "_.pluck" or "_.where" style callback, respectively.
  1888. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1889. * @returns {Mixed} Returns the minimum value.
  1890. * @example
  1891. *
  1892. * _.min([4, 2, 8, 6]);
  1893. * // => 2
  1894. *
  1895. * var stooges = [
  1896. * { 'name': 'moe', 'age': 40 },
  1897. * { 'name': 'larry', 'age': 50 }
  1898. * ];
  1899. *
  1900. * _.min(stooges, function(stooge) { return stooge.age; });
  1901. * // => { 'name': 'moe', 'age': 40 };
  1902. *
  1903. * // using "_.pluck" callback shorthand
  1904. * _.min(stooges, 'age');
  1905. * // => { 'name': 'moe', 'age': 40 };
  1906. */
  1907. function min(collection, callback, thisArg) {
  1908. var computed = Infinity,
  1909. result = computed;
  1910. if (!callback && isArray(collection)) {
  1911. var index = -1,
  1912. length = collection.length;
  1913. while (++index < length) {
  1914. var value = collection[index];
  1915. if (value < result) {
  1916. result = value;
  1917. }
  1918. }
  1919. } else {
  1920. callback = createCallback(callback, thisArg);
  1921. each(collection, function(value, index, collection) {
  1922. var current = callback(value, index, collection);
  1923. if (current < computed) {
  1924. computed = current;
  1925. result = value;
  1926. }
  1927. });
  1928. }
  1929. return result;
  1930. }
  1931. /**
  1932. * Retrieves the value of a specified property from all elements in the `collection`.
  1933. *
  1934. * @static
  1935. * @memberOf _
  1936. * @type Function
  1937. * @category Collections
  1938. * @param {Array|Object|String} collection The collection to iterate over.
  1939. * @param {String} property The property to pluck.
  1940. * @returns {Array} Returns a new array of property values.
  1941. * @example
  1942. *
  1943. * var stooges = [
  1944. * { 'name': 'moe', 'age': 40 },
  1945. * { 'name': 'larry', 'age': 50 }
  1946. * ];
  1947. *
  1948. * _.pluck(stooges, 'name');
  1949. * // => ['moe', 'larry']
  1950. */
  1951. var pluck = map;
  1952. /**
  1953. * Reduces a `collection` to a value that is the accumulated result of running
  1954. * each element in the `collection` through the `callback`, where each successive
  1955. * `callback` execution consumes the return value of the previous execution.
  1956. * If `accumulator` is not passed, the first element of the `collection` will be
  1957. * used as the initial `accumulator` value. The `callback` is bound to `thisArg`
  1958. * and invoked with four arguments; (accumulator, value, index|key, collection).
  1959. *
  1960. * @static
  1961. * @memberOf _
  1962. * @alias foldl, inject
  1963. * @category Collections
  1964. * @param {Array|Object|String} collection The collection to iterate over.
  1965. * @param {Function} [callback=identity] The function called per iteration.
  1966. * @param {Mixed} [accumulator] Initial value of the accumulator.
  1967. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1968. * @returns {Mixed} Returns the accumulated value.
  1969. * @example
  1970. *
  1971. * var sum = _.reduce([1, 2, 3], function(sum, num) {
  1972. * return sum + num;
  1973. * });
  1974. * // => 6
  1975. *
  1976. * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
  1977. * result[key] = num * 3;
  1978. * return result;
  1979. * }, {});
  1980. * // => { 'a': 3, 'b': 6, 'c': 9 }
  1981. */
  1982. function reduce(collection, callback, accumulator, thisArg) {
  1983. var noaccum = arguments.length < 3;
  1984. callback = createCallback(callback, thisArg, 4);
  1985. if (isArray(collection)) {
  1986. var index = -1,
  1987. length = collection.length;
  1988. if (noaccum) {
  1989. accumulator = collection[++index];
  1990. }
  1991. while (++index < length) {
  1992. accumulator = callback(accumulator, collection[index], index, collection);
  1993. }
  1994. } else {
  1995. each(collection, function(value, index, collection) {
  1996. accumulator = noaccum
  1997. ? (noaccum = false, value)
  1998. : callback(accumulator, value, index, collection)
  1999. });
  2000. }
  2001. return accumulator;
  2002. }
  2003. /**
  2004. * This method is similar to `_.reduce`, except that it iterates over a
  2005. * `collection` from right to left.
  2006. *
  2007. * @static
  2008. * @memberOf _
  2009. * @alias foldr
  2010. * @category Collections
  2011. * @param {Array|Object|String} collection The collection to iterate over.
  2012. * @param {Function} [callback=identity] The function called per iteration.
  2013. * @param {Mixed} [accumulator] Initial value of the accumulator.
  2014. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2015. * @returns {Mixed} Returns the accumulated value.
  2016. * @example
  2017. *
  2018. * var list = [[0, 1], [2, 3], [4, 5]];
  2019. * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
  2020. * // => [4, 5, 2, 3, 0, 1]
  2021. */
  2022. function reduceRight(collection, callback, accumulator, thisArg) {
  2023. var iterable = collection,
  2024. length = collection ? collection.length : 0,
  2025. noaccum = arguments.length < 3;
  2026. if (typeof length != 'number') {
  2027. var props = keys(collection);
  2028. length = props.length;
  2029. }
  2030. callback = createCallback(callback, thisArg, 4);
  2031. forEach(collection, function(value, index, collection) {
  2032. index = props ? props[--length] : --length;
  2033. accumulator = noaccum
  2034. ? (noaccum = false, iterable[index])
  2035. : callback(accumulator, iterable[index], index, collection);
  2036. });
  2037. return accumulator;
  2038. }
  2039. /**
  2040. * The opposite of `_.filter`, this method returns the elements of a
  2041. * `collection` that `callback` does **not** return truthy for.
  2042. *
  2043. * If a property name is passed for `callback`, the created "_.pluck" style
  2044. * callback will return the property value of the given element.
  2045. *
  2046. * If an object is passed for `callback`, the created "_.where" style callback
  2047. * will return `true` for elements that have the propeties of the given object,
  2048. * else `false`.
  2049. *
  2050. * @static
  2051. * @memberOf _
  2052. * @category Collections
  2053. * @param {Array|Object|String} collection The collection to iterate over.
  2054. * @param {Function|Object|String} [callback=identity] The function called per
  2055. * iteration. If a property name or object is passed, it will be used to create
  2056. * a "_.pluck" or "_.where" style callback, respectively.
  2057. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2058. * @returns {Array} Returns a new array of elements that did **not** pass the
  2059. * callback check.
  2060. * @example
  2061. *
  2062. * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  2063. * // => [1, 3, 5]
  2064. *
  2065. * var food = [
  2066. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  2067. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  2068. * ];
  2069. *
  2070. * // using "_.pluck" callback shorthand
  2071. * _.reject(food, 'organic');
  2072. * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
  2073. *
  2074. * // using "_.where" callback shorthand
  2075. * _.reject(food, { 'type': 'fruit' });
  2076. * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
  2077. */
  2078. function reject(collection, callback, thisArg) {
  2079. callback = createCallback(callback, thisArg);
  2080. return filter(collection, function(value, index, collection) {
  2081. return !callback(value, index, collection);
  2082. });
  2083. }
  2084. /**
  2085. * Creates an array of shuffled `array` values, using a version of the
  2086. * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
  2087. *
  2088. * @static
  2089. * @memberOf _
  2090. * @category Collections
  2091. * @param {Array|Object|String} collection The collection to shuffle.
  2092. * @returns {Array} Returns a new shuffled collection.
  2093. * @example
  2094. *
  2095. * _.shuffle([1, 2, 3, 4, 5, 6]);
  2096. * // => [4, 1, 6, 3, 5, 2]
  2097. */
  2098. function shuffle(collection) {
  2099. var index = -1,
  2100. length = collection ? collection.length : 0,
  2101. result = Array(typeof length == 'number' ? length : 0);
  2102. forEach(collection, function(value) {
  2103. var rand = floor(nativeRandom() * (++index + 1));
  2104. result[index] = result[rand];
  2105. result[rand] = value;
  2106. });
  2107. return result;
  2108. }
  2109. /**
  2110. * Gets the size of the `collection` by returning `collection.length` for arrays
  2111. * and array-like objects or the number of own enumerable properties for objects.
  2112. *
  2113. * @static
  2114. * @memberOf _
  2115. * @category Collections
  2116. * @param {Array|Object|String} collection The collection to inspect.
  2117. * @returns {Number} Returns `collection.length` or number of own enumerable properties.
  2118. * @example
  2119. *
  2120. * _.size([1, 2]);
  2121. * // => 2
  2122. *
  2123. * _.size({ 'one': 1, 'two': 2, 'three': 3 });
  2124. * // => 3
  2125. *
  2126. * _.size('curly');
  2127. * // => 5
  2128. */
  2129. function size(collection) {
  2130. var length = collection ? collection.length : 0;
  2131. return typeof length == 'number' ? length : keys(collection).length;
  2132. }
  2133. /**
  2134. * Checks if the `callback` returns a truthy value for **any** element of a
  2135. * `collection`. The function returns as soon as it finds passing value, and
  2136. * does not iterate over the entire `collection`. The `callback` is bound to
  2137. * `thisArg` and invoked with three arguments; (value, index|key, collection).
  2138. *
  2139. * If a property name is passed for `callback`, the created "_.pluck" style
  2140. * callback will return the property value of the given element.
  2141. *
  2142. * If an object is passed for `callback`, the created "_.where" style callback
  2143. * will return `true` for elements that have the propeties of the given object,
  2144. * else `false`.
  2145. *
  2146. * @static
  2147. * @memberOf _
  2148. * @alias any
  2149. * @category Collections
  2150. * @param {Array|Object|String} collection The collection to iterate over.
  2151. * @param {Function|Object|String} [callback=identity] The function called per
  2152. * iteration. If a property name or object is passed, it will be used to create
  2153. * a "_.pluck" or "_.where" style callback, respectively.
  2154. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2155. * @returns {Boolean} Returns `true` if any element passes the callback check,
  2156. * else `false`.
  2157. * @example
  2158. *
  2159. * _.some([null, 0, 'yes', false], Boolean);
  2160. * // => true
  2161. *
  2162. * var food = [
  2163. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  2164. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  2165. * ];
  2166. *
  2167. * // using "_.pluck" callback shorthand
  2168. * _.some(food, 'organic');
  2169. * // => true
  2170. *
  2171. * // using "_.where" callback shorthand
  2172. * _.some(food, { 'type': 'meat' });
  2173. * // => false
  2174. */
  2175. function some(collection, callback, thisArg) {
  2176. var result;
  2177. callback = createCallback(callback, thisArg);
  2178. if (isArray(collection)) {
  2179. var index = -1,
  2180. length = collection.length;
  2181. while (++index < length) {
  2182. if ((result = callback(collection[index], index, collection))) {
  2183. break;
  2184. }
  2185. }
  2186. } else {
  2187. each(collection, function(value, index, collection) {
  2188. return (result = callback(value, index, collection)) && indicatorObject;
  2189. });
  2190. }
  2191. return !!result;
  2192. }
  2193. /**
  2194. * Creates an array of elements, sorted in ascending order by the results of
  2195. * running each element in the `collection` through the `callback`. This method
  2196. * performs a stable sort, that is, it will preserve the original sort order of
  2197. * equal elements. The `callback` is bound to `thisArg` and invoked with three
  2198. * arguments; (value, index|key, collection).
  2199. *
  2200. * If a property name is passed for `callback`, the created "_.pluck" style
  2201. * callback will return the property value of the given element.
  2202. *
  2203. * If an object is passed for `callback`, the created "_.where" style callback
  2204. * will return `true` for elements that have the propeties of the given object,
  2205. * else `false`.
  2206. *
  2207. * @static
  2208. * @memberOf _
  2209. * @category Collections
  2210. * @param {Array|Object|String} collection The collection to iterate over.
  2211. * @param {Function|Object|String} [callback=identity] The function called per
  2212. * iteration. If a property name or object is passed, it will be used to create
  2213. * a "_.pluck" or "_.where" style callback, respectively.
  2214. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2215. * @returns {Array} Returns a new array of sorted elements.
  2216. * @example
  2217. *
  2218. * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
  2219. * // => [3, 1, 2]
  2220. *
  2221. * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
  2222. * // => [3, 1, 2]
  2223. *
  2224. * // using "_.pluck" callback shorthand
  2225. * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
  2226. * // => ['apple', 'banana', 'strawberry']
  2227. */
  2228. function sortBy(collection, callback, thisArg) {
  2229. var index = -1,
  2230. length = collection ? collection.length : 0,
  2231. result = Array(typeof length == 'number' ? length : 0);
  2232. callback = createCallback(callback, thisArg);
  2233. forEach(collection, function(value, key, collection) {
  2234. result[++index] = {
  2235. 'criteria': callback(value, key, collection),
  2236. 'index': index,
  2237. 'value': value
  2238. };
  2239. });
  2240. length = result.length;
  2241. result.sort(compareAscending);
  2242. while (length--) {
  2243. result[length] = result[length].value;
  2244. }
  2245. return result;
  2246. }
  2247. /**
  2248. * Converts the `collection` to an array.
  2249. *
  2250. * @static
  2251. * @memberOf _
  2252. * @category Collections
  2253. * @param {Array|Object|String} collection The collection to convert.
  2254. * @returns {Array} Returns the new converted array.
  2255. * @example
  2256. *
  2257. * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
  2258. * // => [2, 3, 4]
  2259. */
  2260. function toArray(collection) {
  2261. if (collection && typeof collection.length == 'number') {
  2262. return slice(collection);
  2263. }
  2264. return values(collection);
  2265. }
  2266. /**
  2267. * Examines each element in a `collection`, returning an array of all elements
  2268. * that have the given `properties`. When checking `properties`, this method
  2269. * performs a deep comparison between values to determine if they are equivalent
  2270. * to each other.
  2271. *
  2272. * @static
  2273. * @memberOf _
  2274. * @type Function
  2275. * @category Collections
  2276. * @param {Array|Object|String} collection The collection to iterate over.
  2277. * @param {Object} properties The object of property values to filter by.
  2278. * @returns {Array} Returns a new array of elements that have the given `properties`.
  2279. * @example
  2280. *
  2281. * var stooges = [
  2282. * { 'name': 'moe', 'age': 40 },
  2283. * { 'name': 'larry', 'age': 50 }
  2284. * ];
  2285. *
  2286. * _.where(stooges, { 'age': 40 });
  2287. * // => [{ 'name': 'moe', 'age': 40 }]
  2288. */
  2289. function where(collection, properties, first) {
  2290. return (first && isEmpty(properties))
  2291. ? null
  2292. : (first ? find : filter)(collection, properties);
  2293. }
  2294. /*--------------------------------------------------------------------------*/
  2295. /**
  2296. * Creates an array with all falsey values of `array` removed. The values
  2297. * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
  2298. *
  2299. * @static
  2300. * @memberOf _
  2301. * @category Arrays
  2302. * @param {Array} array The array to compact.
  2303. * @returns {Array} Returns a new filtered array.
  2304. * @example
  2305. *
  2306. * _.compact([0, 1, false, 2, '', 3]);
  2307. * // => [1, 2, 3]
  2308. */
  2309. function compact(array) {
  2310. var index = -1,
  2311. length = array ? array.length : 0,
  2312. result = [];
  2313. while (++index < length) {
  2314. var value = array[index];
  2315. if (value) {
  2316. result.push(value);
  2317. }
  2318. }
  2319. return result;
  2320. }
  2321. /**
  2322. * Creates an array of `array` elements not present in the other arrays
  2323. * using strict equality for comparisons, i.e. `===`.
  2324. *
  2325. * @static
  2326. * @memberOf _
  2327. * @category Arrays
  2328. * @param {Array} array The array to process.
  2329. * @param {Array} [array1, array2, ...] Arrays to check.
  2330. * @returns {Array} Returns a new array of `array` elements not present in the
  2331. * other arrays.
  2332. * @example
  2333. *
  2334. * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
  2335. * // => [1, 3, 4]
  2336. */
  2337. function difference(array) {
  2338. var index = -1,
  2339. length = array.length,
  2340. flattened = concat.apply(arrayRef, arguments),
  2341. result = [];
  2342. while (++index < length) {
  2343. var value = array[index]
  2344. if (indexOf(flattened, value, length) < 0) {
  2345. result.push(value);
  2346. }
  2347. }
  2348. return result
  2349. }
  2350. /**
  2351. * Gets the first element of the `array`. If a number `n` is passed, the first
  2352. * `n` elements of the `array` are returned. If a `callback` function is passed,
  2353. * the first elements the `callback` returns truthy for are returned. The `callback`
  2354. * is bound to `thisArg` and invoked with three arguments; (value, index, array).
  2355. *
  2356. * If a property name is passed for `callback`, the created "_.pluck" style
  2357. * callback will return the property value of the given element.
  2358. *
  2359. * If an object is passed for `callback`, the created "_.where" style callback
  2360. * will return `true` for elements that have the propeties of the given object,
  2361. * else `false`.
  2362. *
  2363. * @static
  2364. * @memberOf _
  2365. * @alias head, take
  2366. * @category Arrays
  2367. * @param {Array} array The array to query.
  2368. * @param {Function|Object|Number|String} [callback|n] The function called
  2369. * per element or the number of elements to return. If a property name or
  2370. * object is passed, it will be used to create a "_.pluck" or "_.where"
  2371. * style callback, respectively.
  2372. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2373. * @returns {Mixed} Returns the first element(s) of `array`.
  2374. * @example
  2375. *
  2376. * _.first([1, 2, 3]);
  2377. * // => 1
  2378. *
  2379. * _.first([1, 2, 3], 2);
  2380. * // => [1, 2]
  2381. *
  2382. * _.first([1, 2, 3], function(num) {
  2383. * return num < 3;
  2384. * });
  2385. * // => [1, 2]
  2386. *
  2387. * var food = [
  2388. * { 'name': 'banana', 'organic': true },
  2389. * { 'name': 'beet', 'organic': false },
  2390. * ];
  2391. *
  2392. * // using "_.pluck" callback shorthand
  2393. * _.first(food, 'organic');
  2394. * // => [{ 'name': 'banana', 'organic': true }]
  2395. *
  2396. * var food = [
  2397. * { 'name': 'apple', 'type': 'fruit' },
  2398. * { 'name': 'banana', 'type': 'fruit' },
  2399. * { 'name': 'beet', 'type': 'vegetable' }
  2400. * ];
  2401. *
  2402. * // using "_.where" callback shorthand
  2403. * _.first(food, { 'type': 'fruit' });
  2404. * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
  2405. */
  2406. function first(array, callback, thisArg) {
  2407. if (array) {
  2408. var n = 0,
  2409. length = array.length;
  2410. if (typeof callback != 'number' && callback != null) {
  2411. var index = -1;
  2412. callback = createCallback(callback, thisArg);
  2413. while (++index < length && callback(array[index], index, array)) {
  2414. n++;
  2415. }
  2416. } else {
  2417. n = callback;
  2418. if (n == null || thisArg) {
  2419. return array[0];
  2420. }
  2421. }
  2422. return slice(array, 0, nativeMin(nativeMax(0, n), length));
  2423. }
  2424. }
  2425. /**
  2426. * Flattens a nested array (the nesting can be to any depth). If `shallow` is
  2427. * truthy, `array` will only be flattened a single level.
  2428. *
  2429. * @static
  2430. * @memberOf _
  2431. * @category Arrays
  2432. * @param {Array} array The array to compact.
  2433. * @param {Boolean} shallow A flag to indicate only flattening a single level.
  2434. * @returns {Array} Returns a new flattened array.
  2435. * @example
  2436. *
  2437. * _.flatten([1, [2], [3, [[4]]]]);
  2438. * // => [1, 2, 3, 4];
  2439. *
  2440. * _.flatten([1, [2], [3, [[4]]]], true);
  2441. * // => [1, 2, 3, [[4]]];
  2442. */
  2443. function flatten(array, shallow) {
  2444. var index = -1,
  2445. length = array ? array.length : 0,
  2446. result = [];
  2447. while (++index < length) {
  2448. var value = array[index];
  2449. // recursively flatten arrays (susceptible to call stack limits)
  2450. if (isArray(value)) {
  2451. push.apply(result, shallow ? value : flatten(value));
  2452. } else {
  2453. result.push(value);
  2454. }
  2455. }
  2456. return result;
  2457. }
  2458. /**
  2459. * Gets the index at which the first occurrence of `value` is found using
  2460. * strict equality for comparisons, i.e. `===`. If the `array` is already
  2461. * sorted, passing `true` for `fromIndex` will run a faster binary search.
  2462. *
  2463. * @static
  2464. * @memberOf _
  2465. * @category Arrays
  2466. * @param {Array} array The array to search.
  2467. * @param {Mixed} value The value to search for.
  2468. * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to
  2469. * perform a binary search on a sorted `array`.
  2470. * @returns {Number} Returns the index of the matched value or `-1`.
  2471. * @example
  2472. *
  2473. * _.indexOf([1, 2, 3, 1, 2, 3], 2);
  2474. * // => 1
  2475. *
  2476. * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
  2477. * // => 4
  2478. *
  2479. * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
  2480. * // => 2
  2481. */
  2482. function indexOf(array, value, fromIndex) {
  2483. var index = -1,
  2484. length = array ? array.length : 0;
  2485. if (typeof fromIndex == 'number') {
  2486. index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
  2487. } else if (fromIndex) {
  2488. index = sortedIndex(array, value);
  2489. return array[index] === value ? index : -1;
  2490. }
  2491. while (++index < length) {
  2492. if (array[index] === value) {
  2493. return index;
  2494. }
  2495. }
  2496. return -1;
  2497. }
  2498. /**
  2499. * Gets all but the last element of `array`. If a number `n` is passed, the
  2500. * last `n` elements are excluded from the result. If a `callback` function
  2501. * is passed, the last elements the `callback` returns truthy for are excluded
  2502. * from the result. The `callback` is bound to `thisArg` and invoked with three
  2503. * arguments; (value, index, array).
  2504. *
  2505. * If a property name is passed for `callback`, the created "_.pluck" style
  2506. * callback will return the property value of the given element.
  2507. *
  2508. * If an object is passed for `callback`, the created "_.where" style callback
  2509. * will return `true` for elements that have the propeties of the given object,
  2510. * else `false`.
  2511. *
  2512. * @static
  2513. * @memberOf _
  2514. * @category Arrays
  2515. * @param {Array} array The array to query.
  2516. * @param {Function|Object|Number|String} [callback|n=1] The function called
  2517. * per element or the number of elements to exclude. If a property name or
  2518. * object is passed, it will be used to create a "_.pluck" or "_.where"
  2519. * style callback, respectively.
  2520. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2521. * @returns {Array} Returns a slice of `array`.
  2522. * @example
  2523. *
  2524. * _.initial([1, 2, 3]);
  2525. * // => [1, 2]
  2526. *
  2527. * _.initial([1, 2, 3], 2);
  2528. * // => [1]
  2529. *
  2530. * _.initial([1, 2, 3], function(num) {
  2531. * return num > 1;
  2532. * });
  2533. * // => [1]
  2534. *
  2535. * var food = [
  2536. * { 'name': 'beet', 'organic': false },
  2537. * { 'name': 'carrot', 'organic': true }
  2538. * ];
  2539. *
  2540. * // using "_.pluck" callback shorthand
  2541. * _.initial(food, 'organic');
  2542. * // => [{ 'name': 'beet', 'organic': false }]
  2543. *
  2544. * var food = [
  2545. * { 'name': 'banana', 'type': 'fruit' },
  2546. * { 'name': 'beet', 'type': 'vegetable' },
  2547. * { 'name': 'carrot', 'type': 'vegetable' }
  2548. * ];
  2549. *
  2550. * // using "_.where" callback shorthand
  2551. * _.initial(food, { 'type': 'vegetable' });
  2552. * // => [{ 'name': 'banana', 'type': 'fruit' }]
  2553. */
  2554. function initial(array, callback, thisArg) {
  2555. if (!array) {
  2556. return [];
  2557. }
  2558. var n = 0,
  2559. length = array.length;
  2560. if (typeof callback != 'number' && callback != null) {
  2561. var index = length;
  2562. callback = createCallback(callback, thisArg);
  2563. while (index-- && callback(array[index], index, array)) {
  2564. n++;
  2565. }
  2566. } else {
  2567. n = (callback == null || thisArg) ? 1 : callback || n;
  2568. }
  2569. return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
  2570. }
  2571. /**
  2572. * Computes the intersection of all the passed-in arrays using strict equality
  2573. * for comparisons, i.e. `===`.
  2574. *
  2575. * @static
  2576. * @memberOf _
  2577. * @category Arrays
  2578. * @param {Array} [array1, array2, ...] Arrays to process.
  2579. * @returns {Array} Returns a new array of unique elements that are present
  2580. * in **all** of the arrays.
  2581. * @example
  2582. *
  2583. * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
  2584. * // => [1, 2]
  2585. */
  2586. function intersection(array) {
  2587. var args = arguments,
  2588. argsLength = args.length,
  2589. index = -1,
  2590. length = array ? array.length : 0,
  2591. result = [];
  2592. outer:
  2593. while (++index < length) {
  2594. var value = array[index];
  2595. if (indexOf(result, value) < 0) {
  2596. var argsIndex = argsLength;
  2597. while (--argsIndex) {
  2598. if (indexOf(args[argsIndex], value) < 0) {
  2599. continue outer;
  2600. }
  2601. }
  2602. result.push(value);
  2603. }
  2604. }
  2605. return result;
  2606. }
  2607. /**
  2608. * Gets the last element of the `array`. If a number `n` is passed, the last
  2609. * `n` elements of the `array` are returned. If a `callback` function is passed,
  2610. * the last elements the `callback` returns truthy for are returned. The `callback`
  2611. * is bound to `thisArg` and invoked with three arguments; (value, index, array).
  2612. *
  2613. *
  2614. * If a property name is passed for `callback`, the created "_.pluck" style
  2615. * callback will return the property value of the given element.
  2616. *
  2617. * If an object is passed for `callback`, the created "_.where" style callback
  2618. * will return `true` for elements that have the propeties of the given object,
  2619. * else `false`.
  2620. *
  2621. * @static
  2622. * @memberOf _
  2623. * @category Arrays
  2624. * @param {Array} array The array to query.
  2625. * @param {Function|Object|Number|String} [callback|n] The function called
  2626. * per element or the number of elements to return. If a property name or
  2627. * object is passed, it will be used to create a "_.pluck" or "_.where"
  2628. * style callback, respectively.
  2629. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2630. * @returns {Mixed} Returns the last element(s) of `array`.
  2631. * @example
  2632. *
  2633. * _.last([1, 2, 3]);
  2634. * // => 3
  2635. *
  2636. * _.last([1, 2, 3], 2);
  2637. * // => [2, 3]
  2638. *
  2639. * _.last([1, 2, 3], function(num) {
  2640. * return num > 1;
  2641. * });
  2642. * // => [2, 3]
  2643. *
  2644. * var food = [
  2645. * { 'name': 'beet', 'organic': false },
  2646. * { 'name': 'carrot', 'organic': true }
  2647. * ];
  2648. *
  2649. * // using "_.pluck" callback shorthand
  2650. * _.last(food, 'organic');
  2651. * // => [{ 'name': 'carrot', 'organic': true }]
  2652. *
  2653. * var food = [
  2654. * { 'name': 'banana', 'type': 'fruit' },
  2655. * { 'name': 'beet', 'type': 'vegetable' },
  2656. * { 'name': 'carrot', 'type': 'vegetable' }
  2657. * ];
  2658. *
  2659. * // using "_.where" callback shorthand
  2660. * _.last(food, { 'type': 'vegetable' });
  2661. * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
  2662. */
  2663. function last(array, callback, thisArg) {
  2664. if (array) {
  2665. var n = 0,
  2666. length = array.length;
  2667. if (typeof callback != 'number' && callback != null) {
  2668. var index = length;
  2669. callback = createCallback(callback, thisArg);
  2670. while (index-- && callback(array[index], index, array)) {
  2671. n++;
  2672. }
  2673. } else {
  2674. n = callback;
  2675. if (n == null || thisArg) {
  2676. return array[length - 1];
  2677. }
  2678. }
  2679. return slice(array, nativeMax(0, length - n));
  2680. }
  2681. }
  2682. /**
  2683. * Gets the index at which the last occurrence of `value` is found using strict
  2684. * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
  2685. * as the offset from the end of the collection.
  2686. *
  2687. * @static
  2688. * @memberOf _
  2689. * @category Arrays
  2690. * @param {Array} array The array to search.
  2691. * @param {Mixed} value The value to search for.
  2692. * @param {Number} [fromIndex=array.length-1] The index to search from.
  2693. * @returns {Number} Returns the index of the matched value or `-1`.
  2694. * @example
  2695. *
  2696. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
  2697. * // => 4
  2698. *
  2699. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
  2700. * // => 1
  2701. */
  2702. function lastIndexOf(array, value, fromIndex) {
  2703. var index = array ? array.length : 0;
  2704. if (typeof fromIndex == 'number') {
  2705. index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
  2706. }
  2707. while (index--) {
  2708. if (array[index] === value) {
  2709. return index;
  2710. }
  2711. }
  2712. return -1;
  2713. }
  2714. /**
  2715. * Creates an object composed from arrays of `keys` and `values`. Pass either
  2716. * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or
  2717. * two arrays, one of `keys` and one of corresponding `values`.
  2718. *
  2719. * @static
  2720. * @memberOf _
  2721. * @category Arrays
  2722. * @param {Array} keys The array of keys.
  2723. * @param {Array} [values=[]] The array of values.
  2724. * @returns {Object} Returns an object composed of the given keys and
  2725. * corresponding values.
  2726. * @example
  2727. *
  2728. * _.object(['moe', 'larry'], [30, 40]);
  2729. * // => { 'moe': 30, 'larry': 40 }
  2730. */
  2731. function object(keys, values) {
  2732. var index = -1,
  2733. length = keys ? keys.length : 0,
  2734. result = {};
  2735. while (++index < length) {
  2736. var key = keys[index];
  2737. if (values) {
  2738. result[key] = values[index];
  2739. } else {
  2740. result[key[0]] = key[1];
  2741. }
  2742. }
  2743. return result;
  2744. }
  2745. /**
  2746. * Creates an array of numbers (positive and/or negative) progressing from
  2747. * `start` up to but not including `end`.
  2748. *
  2749. * @static
  2750. * @memberOf _
  2751. * @category Arrays
  2752. * @param {Number} [start=0] The start of the range.
  2753. * @param {Number} end The end of the range.
  2754. * @param {Number} [step=1] The value to increment or descrement by.
  2755. * @returns {Array} Returns a new range array.
  2756. * @example
  2757. *
  2758. * _.range(10);
  2759. * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  2760. *
  2761. * _.range(1, 11);
  2762. * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  2763. *
  2764. * _.range(0, 30, 5);
  2765. * // => [0, 5, 10, 15, 20, 25]
  2766. *
  2767. * _.range(0, -10, -1);
  2768. * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
  2769. *
  2770. * _.range(0);
  2771. * // => []
  2772. */
  2773. function range(start, end, step) {
  2774. start = +start || 0;
  2775. step = +step || 1;
  2776. if (end == null) {
  2777. end = start;
  2778. start = 0;
  2779. }
  2780. // use `Array(length)` so V8 will avoid the slower "dictionary" mode
  2781. // http://youtu.be/XAqIpGU8ZZk#t=17m25s
  2782. var index = -1,
  2783. length = nativeMax(0, ceil((end - start) / step)),
  2784. result = Array(length);
  2785. while (++index < length) {
  2786. result[index] = start;
  2787. start += step;
  2788. }
  2789. return result;
  2790. }
  2791. /**
  2792. * The opposite of `_.initial`, this method gets all but the first value of `array`.
  2793. * If a number `n` is passed, the first `n` values are excluded from the result.
  2794. * If a `callback` function is passed, the first elements the `callback` returns
  2795. * truthy for are excluded from the result. The `callback` is bound to `thisArg`
  2796. * and invoked with three arguments; (value, index, array).
  2797. *
  2798. * If a property name is passed for `callback`, the created "_.pluck" style
  2799. * callback will return the property value of the given element.
  2800. *
  2801. * If an object is passed for `callback`, the created "_.where" style callback
  2802. * will return `true` for elements that have the propeties of the given object,
  2803. * else `false`.
  2804. *
  2805. * @static
  2806. * @memberOf _
  2807. * @alias drop, tail
  2808. * @category Arrays
  2809. * @param {Array} array The array to query.
  2810. * @param {Function|Object|Number|String} [callback|n=1] The function called
  2811. * per element or the number of elements to exclude. If a property name or
  2812. * object is passed, it will be used to create a "_.pluck" or "_.where"
  2813. * style callback, respectively.
  2814. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2815. * @returns {Array} Returns a slice of `array`.
  2816. * @example
  2817. *
  2818. * _.rest([1, 2, 3]);
  2819. * // => [2, 3]
  2820. *
  2821. * _.rest([1, 2, 3], 2);
  2822. * // => [3]
  2823. *
  2824. * _.rest([1, 2, 3], function(num) {
  2825. * return num < 3;
  2826. * });
  2827. * // => [3]
  2828. *
  2829. * var food = [
  2830. * { 'name': 'banana', 'organic': true },
  2831. * { 'name': 'beet', 'organic': false },
  2832. * ];
  2833. *
  2834. * // using "_.pluck" callback shorthand
  2835. * _.rest(food, 'organic');
  2836. * // => [{ 'name': 'beet', 'organic': false }]
  2837. *
  2838. * var food = [
  2839. * { 'name': 'apple', 'type': 'fruit' },
  2840. * { 'name': 'banana', 'type': 'fruit' },
  2841. * { 'name': 'beet', 'type': 'vegetable' }
  2842. * ];
  2843. *
  2844. * // using "_.where" callback shorthand
  2845. * _.rest(food, { 'type': 'fruit' });
  2846. * // => [{ 'name': 'beet', 'type': 'vegetable' }]
  2847. */
  2848. function rest(array, callback, thisArg) {
  2849. if (typeof callback != 'number' && callback != null) {
  2850. var n = 0,
  2851. index = -1,
  2852. length = array ? array.length : 0;
  2853. callback = createCallback(callback, thisArg);
  2854. while (++index < length && callback(array[index], index, array)) {
  2855. n++;
  2856. }
  2857. } else {
  2858. n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
  2859. }
  2860. return slice(array, n);
  2861. }
  2862. /**
  2863. * Uses a binary search to determine the smallest index at which the `value`
  2864. * should be inserted into `array` in order to maintain the sort order of the
  2865. * sorted `array`. If `callback` is passed, it will be executed for `value` and
  2866. * each element in `array` to compute their sort ranking. The `callback` is
  2867. * bound to `thisArg` and invoked with one argument; (value).
  2868. *
  2869. * If a property name is passed for `callback`, the created "_.pluck" style
  2870. * callback will return the property value of the given element.
  2871. *
  2872. * If an object is passed for `callback`, the created "_.where" style callback
  2873. * will return `true` for elements that have the propeties of the given object,
  2874. * else `false`.
  2875. *
  2876. * @static
  2877. * @memberOf _
  2878. * @category Arrays
  2879. * @param {Array} array The array to iterate over.
  2880. * @param {Mixed} value The value to evaluate.
  2881. * @param {Function|Object|String} [callback=identity] The function called per
  2882. * iteration. If a property name or object is passed, it will be used to create
  2883. * a "_.pluck" or "_.where" style callback, respectively.
  2884. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2885. * @returns {Number} Returns the index at which the value should be inserted
  2886. * into `array`.
  2887. * @example
  2888. *
  2889. * _.sortedIndex([20, 30, 50], 40);
  2890. * // => 2
  2891. *
  2892. * // using "_.pluck" callback shorthand
  2893. * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
  2894. * // => 2
  2895. *
  2896. * var dict = {
  2897. * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
  2898. * };
  2899. *
  2900. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  2901. * return dict.wordToNumber[word];
  2902. * });
  2903. * // => 2
  2904. *
  2905. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  2906. * return this.wordToNumber[word];
  2907. * }, dict);
  2908. * // => 2
  2909. */
  2910. function sortedIndex(array, value, callback, thisArg) {
  2911. var low = 0,
  2912. high = array ? array.length : low;
  2913. // explicitly reference `identity` for better inlining in Firefox
  2914. callback = callback ? createCallback(callback, thisArg, 1) : identity;
  2915. value = callback(value);
  2916. while (low < high) {
  2917. var mid = (low + high) >>> 1;
  2918. callback(array[mid]) < value
  2919. ? low = mid + 1
  2920. : high = mid;
  2921. }
  2922. return low;
  2923. }
  2924. /**
  2925. * Computes the union of the passed-in arrays using strict equality for
  2926. * comparisons, i.e. `===`.
  2927. *
  2928. * @static
  2929. * @memberOf _
  2930. * @category Arrays
  2931. * @param {Array} [array1, array2, ...] Arrays to process.
  2932. * @returns {Array} Returns a new array of unique values, in order, that are
  2933. * present in one or more of the arrays.
  2934. * @example
  2935. *
  2936. * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
  2937. * // => [1, 2, 3, 101, 10]
  2938. */
  2939. function union() {
  2940. return uniq(concat.apply(arrayRef, arguments));
  2941. }
  2942. /**
  2943. * Creates a duplicate-value-free version of the `array` using strict equality
  2944. * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
  2945. * for `isSorted` will run a faster algorithm. If `callback` is passed, each
  2946. * element of `array` is passed through a callback` before uniqueness is computed.
  2947. * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
  2948. *
  2949. * If a property name is passed for `callback`, the created "_.pluck" style
  2950. * callback will return the property value of the given element.
  2951. *
  2952. * If an object is passed for `callback`, the created "_.where" style callback
  2953. * will return `true` for elements that have the propeties of the given object,
  2954. * else `false`.
  2955. *
  2956. * @static
  2957. * @memberOf _
  2958. * @alias unique
  2959. * @category Arrays
  2960. * @param {Array} array The array to process.
  2961. * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
  2962. * @param {Function|Object|String} [callback=identity] The function called per
  2963. * iteration. If a property name or object is passed, it will be used to create
  2964. * a "_.pluck" or "_.where" style callback, respectively.
  2965. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2966. * @returns {Array} Returns a duplicate-value-free array.
  2967. * @example
  2968. *
  2969. * _.uniq([1, 2, 1, 3, 1]);
  2970. * // => [1, 2, 3]
  2971. *
  2972. * _.uniq([1, 1, 2, 2, 3], true);
  2973. * // => [1, 2, 3]
  2974. *
  2975. * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); });
  2976. * // => [1, 2, 3]
  2977. *
  2978. * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
  2979. * // => [1, 2, 3]
  2980. *
  2981. * // using "_.pluck" callback shorthand
  2982. * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
  2983. * // => [{ 'x': 1 }, { 'x': 2 }]
  2984. */
  2985. function uniq(array, isSorted, callback, thisArg) {
  2986. var index = -1,
  2987. length = array ? array.length : 0,
  2988. result = [],
  2989. seen = result;
  2990. if (typeof isSorted == 'function') {
  2991. thisArg = callback;
  2992. callback = isSorted;
  2993. isSorted = false;
  2994. }
  2995. if (callback) {
  2996. seen = [];
  2997. callback = createCallback(callback, thisArg);
  2998. }
  2999. while (++index < length) {
  3000. var value = array[index],
  3001. computed = callback ? callback(value, index, array) : value;
  3002. if (isSorted
  3003. ? !index || seen[seen.length - 1] !== computed
  3004. : indexOf(seen, computed) < 0
  3005. ) {
  3006. if (callback) {
  3007. seen.push(computed);
  3008. }
  3009. result.push(value);
  3010. }
  3011. }
  3012. return result;
  3013. }
  3014. /**
  3015. * Creates an array with all occurrences of the passed values removed using
  3016. * strict equality for comparisons, i.e. `===`.
  3017. *
  3018. * @static
  3019. * @memberOf _
  3020. * @category Arrays
  3021. * @param {Array} array The array to filter.
  3022. * @param {Mixed} [value1, value2, ...] Values to remove.
  3023. * @returns {Array} Returns a new filtered array.
  3024. * @example
  3025. *
  3026. * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
  3027. * // => [2, 3, 4]
  3028. */
  3029. function without(array) {
  3030. var index = -1,
  3031. length = array.length,
  3032. result = [];
  3033. while (++index < length) {
  3034. var value = array[index]
  3035. if (indexOf(arguments, value, 1) < 0) {
  3036. result.push(value);
  3037. }
  3038. }
  3039. return result
  3040. }
  3041. /**
  3042. * Groups the elements of each array at their corresponding indexes. Useful for
  3043. * separate data sources that are coordinated through matching array indexes.
  3044. * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix
  3045. * in a similar fashion.
  3046. *
  3047. * @static
  3048. * @memberOf _
  3049. * @category Arrays
  3050. * @param {Array} [array1, array2, ...] Arrays to process.
  3051. * @returns {Array} Returns a new array of grouped elements.
  3052. * @example
  3053. *
  3054. * _.zip(['moe', 'larry'], [30, 40], [true, false]);
  3055. * // => [['moe', 30, true], ['larry', 40, false]]
  3056. */
  3057. function zip(array) {
  3058. var index = -1,
  3059. length = array ? max(pluck(arguments, 'length')) : 0,
  3060. result = Array(length);
  3061. while (++index < length) {
  3062. result[index] = pluck(arguments, index);
  3063. }
  3064. return result;
  3065. }
  3066. /*--------------------------------------------------------------------------*/
  3067. /**
  3068. * Creates a function that is restricted to executing `func` only after it is
  3069. * called `n` times. The `func` is executed with the `this` binding of the
  3070. * created function.
  3071. *
  3072. * @static
  3073. * @memberOf _
  3074. * @category Functions
  3075. * @param {Number} n The number of times the function must be called before
  3076. * it is executed.
  3077. * @param {Function} func The function to restrict.
  3078. * @returns {Function} Returns the new restricted function.
  3079. * @example
  3080. *
  3081. * var renderNotes = _.after(notes.length, render);
  3082. * _.forEach(notes, function(note) {
  3083. * note.asyncSave({ 'success': renderNotes });
  3084. * });
  3085. * // `renderNotes` is run once, after all notes have saved
  3086. */
  3087. function after(n, func) {
  3088. if (n < 1) {
  3089. return func();
  3090. }
  3091. return function() {
  3092. if (--n < 1) {
  3093. return func.apply(this, arguments);
  3094. }
  3095. };
  3096. }
  3097. /**
  3098. * Creates a function that, when called, invokes `func` with the `this`
  3099. * binding of `thisArg` and prepends any additional `bind` arguments to those
  3100. * passed to the bound function.
  3101. *
  3102. * @static
  3103. * @memberOf _
  3104. * @category Functions
  3105. * @param {Function} func The function to bind.
  3106. * @param {Mixed} [thisArg] The `this` binding of `func`.
  3107. * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
  3108. * @returns {Function} Returns the new bound function.
  3109. * @example
  3110. *
  3111. * var func = function(greeting) {
  3112. * return greeting + ' ' + this.name;
  3113. * };
  3114. *
  3115. * func = _.bind(func, { 'name': 'moe' }, 'hi');
  3116. * func();
  3117. * // => 'hi moe'
  3118. */
  3119. function bind(func, thisArg) {
  3120. // use `Function#bind` if it exists and is fast
  3121. // (in V8 `Function#bind` is slower except when partially applied)
  3122. return isBindFast || (nativeBind && arguments.length > 2)
  3123. ? nativeBind.call.apply(nativeBind, arguments)
  3124. : createBound(func, thisArg, slice(arguments, 2));
  3125. }
  3126. /**
  3127. * Binds methods on `object` to `object`, overwriting the existing method.
  3128. * Method names may be specified as individual arguments or as arrays of method
  3129. * names. If no method names are provided, all the function properties of `object`
  3130. * will be bound.
  3131. *
  3132. * @static
  3133. * @memberOf _
  3134. * @category Functions
  3135. * @param {Object} object The object to bind and assign the bound methods to.
  3136. * @param {String} [methodName1, methodName2, ...] Method names on the object to bind.
  3137. * @returns {Object} Returns `object`.
  3138. * @example
  3139. *
  3140. * var view = {
  3141. * 'label': 'docs',
  3142. * 'onClick': function() { alert('clicked ' + this.label); }
  3143. * };
  3144. *
  3145. * _.bindAll(view);
  3146. * jQuery('#docs').on('click', view.onClick);
  3147. * // => alerts 'clicked docs', when the button is clicked
  3148. */
  3149. function bindAll(object) {
  3150. var funcs = concat.apply(arrayRef, arguments),
  3151. index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
  3152. length = funcs.length;
  3153. while (++index < length) {
  3154. var key = funcs[index];
  3155. object[key] = bind(object[key], object);
  3156. }
  3157. return object;
  3158. }
  3159. /**
  3160. * Creates a function that is the composition of the passed functions,
  3161. * where each function consumes the return value of the function that follows.
  3162. * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
  3163. * Each function is executed with the `this` binding of the composed function.
  3164. *
  3165. * @static
  3166. * @memberOf _
  3167. * @category Functions
  3168. * @param {Function} [func1, func2, ...] Functions to compose.
  3169. * @returns {Function} Returns the new composed function.
  3170. * @example
  3171. *
  3172. * var greet = function(name) { return 'hi ' + name; };
  3173. * var exclaim = function(statement) { return statement + '!'; };
  3174. * var welcome = _.compose(exclaim, greet);
  3175. * welcome('moe');
  3176. * // => 'hi moe!'
  3177. */
  3178. function compose() {
  3179. var funcs = arguments;
  3180. return function() {
  3181. var args = arguments,
  3182. length = funcs.length;
  3183. while (length--) {
  3184. args = [funcs[length].apply(this, args)];
  3185. }
  3186. return args[0];
  3187. };
  3188. }
  3189. /**
  3190. * Creates a function that will delay the execution of `func` until after
  3191. * `wait` milliseconds have elapsed since the last time it was invoked. Pass
  3192. * `true` for `immediate` to cause debounce to invoke `func` on the leading,
  3193. * instead of the trailing, edge of the `wait` timeout. Subsequent calls to
  3194. * the debounced function will return the result of the last `func` call.
  3195. *
  3196. * @static
  3197. * @memberOf _
  3198. * @category Functions
  3199. * @param {Function} func The function to debounce.
  3200. * @param {Number} wait The number of milliseconds to delay.
  3201. * @param {Boolean} immediate A flag to indicate execution is on the leading
  3202. * edge of the timeout.
  3203. * @returns {Function} Returns the new debounced function.
  3204. * @example
  3205. *
  3206. * var lazyLayout = _.debounce(calculateLayout, 300);
  3207. * jQuery(window).on('resize', lazyLayout);
  3208. */
  3209. function debounce(func, wait, immediate) {
  3210. var args,
  3211. result,
  3212. thisArg,
  3213. timeoutId;
  3214. function delayed() {
  3215. timeoutId = null;
  3216. if (!immediate) {
  3217. result = func.apply(thisArg, args);
  3218. }
  3219. }
  3220. return function() {
  3221. var isImmediate = immediate && !timeoutId;
  3222. args = arguments;
  3223. thisArg = this;
  3224. clearTimeout(timeoutId);
  3225. timeoutId = setTimeout(delayed, wait);
  3226. if (isImmediate) {
  3227. result = func.apply(thisArg, args);
  3228. }
  3229. return result;
  3230. };
  3231. }
  3232. /**
  3233. * Executes the `func` function after `wait` milliseconds. Additional arguments
  3234. * will be passed to `func` when it is invoked.
  3235. *
  3236. * @static
  3237. * @memberOf _
  3238. * @category Functions
  3239. * @param {Function} func The function to delay.
  3240. * @param {Number} wait The number of milliseconds to delay execution.
  3241. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
  3242. * @returns {Number} Returns the `setTimeout` timeout id.
  3243. * @example
  3244. *
  3245. * var log = _.bind(console.log, console);
  3246. * _.delay(log, 1000, 'logged later');
  3247. * // => 'logged later' (Appears after one second.)
  3248. */
  3249. function delay(func, wait) {
  3250. var args = slice(arguments, 2);
  3251. return setTimeout(function() { func.apply(undefined, args); }, wait);
  3252. }
  3253. /**
  3254. * Defers executing the `func` function until the current call stack has cleared.
  3255. * Additional arguments will be passed to `func` when it is invoked.
  3256. *
  3257. * @static
  3258. * @memberOf _
  3259. * @category Functions
  3260. * @param {Function} func The function to defer.
  3261. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
  3262. * @returns {Number} Returns the `setTimeout` timeout id.
  3263. * @example
  3264. *
  3265. * _.defer(function() { alert('deferred'); });
  3266. * // returns from the function before `alert` is called
  3267. */
  3268. function defer(func) {
  3269. var args = slice(arguments, 1);
  3270. return setTimeout(function() { func.apply(undefined, args); }, 1);
  3271. }
  3272. // use `setImmediate` if it's available in Node.js
  3273. if (isV8 && freeModule && typeof setImmediate == 'function') {
  3274. defer = bind(setImmediate, window);
  3275. }
  3276. /**
  3277. * Creates a function that memoizes the result of `func`. If `resolver` is
  3278. * passed, it will be used to determine the cache key for storing the result
  3279. * based on the arguments passed to the memoized function. By default, the first
  3280. * argument passed to the memoized function is used as the cache key. The `func`
  3281. * is executed with the `this` binding of the memoized function.
  3282. *
  3283. * @static
  3284. * @memberOf _
  3285. * @category Functions
  3286. * @param {Function} func The function to have its output memoized.
  3287. * @param {Function} [resolver] A function used to resolve the cache key.
  3288. * @returns {Function} Returns the new memoizing function.
  3289. * @example
  3290. *
  3291. * var fibonacci = _.memoize(function(n) {
  3292. * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
  3293. * });
  3294. */
  3295. function memoize(func, resolver) {
  3296. var cache = {};
  3297. return function() {
  3298. var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + '';
  3299. return hasOwnProperty.call(cache, key)
  3300. ? cache[key]
  3301. : (cache[key] = func.apply(this, arguments));
  3302. };
  3303. }
  3304. /**
  3305. * Creates a function that is restricted to execute `func` once. Repeat calls to
  3306. * the function will return the value of the first call. The `func` is executed
  3307. * with the `this` binding of the created function.
  3308. *
  3309. * @static
  3310. * @memberOf _
  3311. * @category Functions
  3312. * @param {Function} func The function to restrict.
  3313. * @returns {Function} Returns the new restricted function.
  3314. * @example
  3315. *
  3316. * var initialize = _.once(createApplication);
  3317. * initialize();
  3318. * initialize();
  3319. * // `initialize` executes `createApplication` once
  3320. */
  3321. function once(func) {
  3322. var ran,
  3323. result;
  3324. return function() {
  3325. if (ran) {
  3326. return result;
  3327. }
  3328. ran = true;
  3329. result = func.apply(this, arguments);
  3330. // clear the `func` variable so the function may be garbage collected
  3331. func = null;
  3332. return result;
  3333. };
  3334. }
  3335. /**
  3336. * Creates a function that, when called, invokes `func` with any additional
  3337. * `partial` arguments prepended to those passed to the new function. This
  3338. * method is similar to `_.bind`, except it does **not** alter the `this` binding.
  3339. *
  3340. * @static
  3341. * @memberOf _
  3342. * @category Functions
  3343. * @param {Function} func The function to partially apply arguments to.
  3344. * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
  3345. * @returns {Function} Returns the new partially applied function.
  3346. * @example
  3347. *
  3348. * var greet = function(greeting, name) { return greeting + ' ' + name; };
  3349. * var hi = _.partial(greet, 'hi');
  3350. * hi('moe');
  3351. * // => 'hi moe'
  3352. */
  3353. function partial(func) {
  3354. return createBound(func, slice(arguments, 1));
  3355. }
  3356. /**
  3357. * Creates a function that, when executed, will only call the `func`
  3358. * function at most once per every `wait` milliseconds. If the throttled
  3359. * function is invoked more than once during the `wait` timeout, `func` will
  3360. * also be called on the trailing edge of the timeout. Subsequent calls to the
  3361. * throttled function will return the result of the last `func` call.
  3362. *
  3363. * @static
  3364. * @memberOf _
  3365. * @category Functions
  3366. * @param {Function} func The function to throttle.
  3367. * @param {Number} wait The number of milliseconds to throttle executions to.
  3368. * @returns {Function} Returns the new throttled function.
  3369. * @example
  3370. *
  3371. * var throttled = _.throttle(updatePosition, 100);
  3372. * jQuery(window).on('scroll', throttled);
  3373. */
  3374. function throttle(func, wait) {
  3375. var args,
  3376. result,
  3377. thisArg,
  3378. timeoutId,
  3379. lastCalled = 0;
  3380. function trailingCall() {
  3381. lastCalled = new Date;
  3382. timeoutId = null;
  3383. result = func.apply(thisArg, args);
  3384. }
  3385. return function() {
  3386. var now = new Date,
  3387. remaining = wait - (now - lastCalled);
  3388. args = arguments;
  3389. thisArg = this;
  3390. if (remaining <= 0) {
  3391. clearTimeout(timeoutId);
  3392. timeoutId = null;
  3393. lastCalled = now;
  3394. result = func.apply(thisArg, args);
  3395. }
  3396. else if (!timeoutId) {
  3397. timeoutId = setTimeout(trailingCall, remaining);
  3398. }
  3399. return result;
  3400. };
  3401. }
  3402. /**
  3403. * Creates a function that passes `value` to the `wrapper` function as its
  3404. * first argument. Additional arguments passed to the function are appended
  3405. * to those passed to the `wrapper` function. The `wrapper` is executed with
  3406. * the `this` binding of the created function.
  3407. *
  3408. * @static
  3409. * @memberOf _
  3410. * @category Functions
  3411. * @param {Mixed} value The value to wrap.
  3412. * @param {Function} wrapper The wrapper function.
  3413. * @returns {Function} Returns the new function.
  3414. * @example
  3415. *
  3416. * var hello = function(name) { return 'hello ' + name; };
  3417. * hello = _.wrap(hello, function(func) {
  3418. * return 'before, ' + func('moe') + ', after';
  3419. * });
  3420. * hello();
  3421. * // => 'before, hello moe, after'
  3422. */
  3423. function wrap(value, wrapper) {
  3424. return function() {
  3425. var args = [value];
  3426. push.apply(args, arguments);
  3427. return wrapper.apply(this, args);
  3428. };
  3429. }
  3430. /*--------------------------------------------------------------------------*/
  3431. /**
  3432. * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
  3433. * corresponding HTML entities.
  3434. *
  3435. * @static
  3436. * @memberOf _
  3437. * @category Utilities
  3438. * @param {String} string The string to escape.
  3439. * @returns {String} Returns the escaped string.
  3440. * @example
  3441. *
  3442. * _.escape('Moe, Larry & Curly');
  3443. * // => 'Moe, Larry &amp; Curly'
  3444. */
  3445. function escape(string) {
  3446. return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar);
  3447. }
  3448. /**
  3449. * This function returns the first argument passed to it.
  3450. *
  3451. * @static
  3452. * @memberOf _
  3453. * @category Utilities
  3454. * @param {Mixed} value Any value.
  3455. * @returns {Mixed} Returns `value`.
  3456. * @example
  3457. *
  3458. * var moe = { 'name': 'moe' };
  3459. * moe === _.identity(moe);
  3460. * // => true
  3461. */
  3462. function identity(value) {
  3463. return value;
  3464. }
  3465. /**
  3466. * Adds functions properties of `object` to the `lodash` function and chainable
  3467. * wrapper.
  3468. *
  3469. * @static
  3470. * @memberOf _
  3471. * @category Utilities
  3472. * @param {Object} object The object of function properties to add to `lodash`.
  3473. * @example
  3474. *
  3475. * _.mixin({
  3476. * 'capitalize': function(string) {
  3477. * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
  3478. * }
  3479. * });
  3480. *
  3481. * _.capitalize('moe');
  3482. * // => 'Moe'
  3483. *
  3484. * _('moe').capitalize();
  3485. * // => 'Moe'
  3486. */
  3487. function mixin(object) {
  3488. forEach(functions(object), function(methodName) {
  3489. var func = lodash[methodName] = object[methodName];
  3490. lodash.prototype[methodName] = function() {
  3491. var args = [this.__wrapped__];
  3492. push.apply(args, arguments);
  3493. var result = func.apply(lodash, args);
  3494. if (this.__chain__) {
  3495. result = new lodash(result);
  3496. result.__chain__ = true;
  3497. }
  3498. return result;
  3499. };
  3500. });
  3501. }
  3502. /**
  3503. * Reverts the '_' variable to its previous value and returns a reference to
  3504. * the `lodash` function.
  3505. *
  3506. * @static
  3507. * @memberOf _
  3508. * @category Utilities
  3509. * @returns {Function} Returns the `lodash` function.
  3510. * @example
  3511. *
  3512. * var lodash = _.noConflict();
  3513. */
  3514. function noConflict() {
  3515. window._ = oldDash;
  3516. return this;
  3517. }
  3518. /**
  3519. * Produces a random number between `min` and `max` (inclusive). If only one
  3520. * argument is passed, a number between `0` and the given number will be returned.
  3521. *
  3522. * @static
  3523. * @memberOf _
  3524. * @category Utilities
  3525. * @param {Number} [min=0] The minimum possible value.
  3526. * @param {Number} [max=1] The maximum possible value.
  3527. * @returns {Number} Returns a random number.
  3528. * @example
  3529. *
  3530. * _.random(0, 5);
  3531. * // => a number between 0 and 5
  3532. *
  3533. * _.random(5);
  3534. * // => also a number between 0 and 5
  3535. */
  3536. function random(min, max) {
  3537. if (min == null && max == null) {
  3538. max = 1;
  3539. }
  3540. min = +min || 0;
  3541. if (max == null) {
  3542. max = min;
  3543. min = 0;
  3544. }
  3545. return min + floor(nativeRandom() * ((+max || 0) - min + 1));
  3546. }
  3547. /**
  3548. * Resolves the value of `property` on `object`. If `property` is a function,
  3549. * it will be invoked and its result returned, else the property value is
  3550. * returned. If `object` is falsey, then `null` is returned.
  3551. *
  3552. * @static
  3553. * @memberOf _
  3554. * @category Utilities
  3555. * @param {Object} object The object to inspect.
  3556. * @param {String} property The property to get the value of.
  3557. * @returns {Mixed} Returns the resolved value.
  3558. * @example
  3559. *
  3560. * var object = {
  3561. * 'cheese': 'crumpets',
  3562. * 'stuff': function() {
  3563. * return 'nonsense';
  3564. * }
  3565. * };
  3566. *
  3567. * _.result(object, 'cheese');
  3568. * // => 'crumpets'
  3569. *
  3570. * _.result(object, 'stuff');
  3571. * // => 'nonsense'
  3572. */
  3573. function result(object, property) {
  3574. var value = object ? object[property] : null;
  3575. return isFunction(value) ? object[property]() : value;
  3576. }
  3577. /**
  3578. * A micro-templating method that handles arbitrary delimiters, preserves
  3579. * whitespace, and correctly escapes quotes within interpolated code.
  3580. *
  3581. * Note: In the development build, `_.template` utilizes sourceURLs for easier
  3582. * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
  3583. *
  3584. * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp`
  3585. * build and using precompiled templates, or loading Lo-Dash in a sandbox.
  3586. *
  3587. * For more information on precompiling templates see:
  3588. * http://lodash.com/#custom-builds
  3589. *
  3590. * For more information on Chrome extension sandboxes see:
  3591. * http://developer.chrome.com/stable/extensions/sandboxingEval.html
  3592. *
  3593. * @static
  3594. * @memberOf _
  3595. * @category Utilities
  3596. * @param {String} text The template text.
  3597. * @param {Obect} data The data object used to populate the text.
  3598. * @param {Object} options The options object.
  3599. * escape - The "escape" delimiter regexp.
  3600. * evaluate - The "evaluate" delimiter regexp.
  3601. * interpolate - The "interpolate" delimiter regexp.
  3602. * sourceURL - The sourceURL of the template's compiled source.
  3603. * variable - The data object variable name.
  3604. *
  3605. * @returns {Function|String} Returns a compiled function when no `data` object
  3606. * is given, else it returns the interpolated text.
  3607. * @example
  3608. *
  3609. * // using a compiled template
  3610. * var compiled = _.template('hello <%= name %>');
  3611. * compiled({ 'name': 'moe' });
  3612. * // => 'hello moe'
  3613. *
  3614. * var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
  3615. * _.template(list, { 'people': ['moe', 'larry'] });
  3616. * // => '<li>moe</li><li>larry</li>'
  3617. *
  3618. * // using the "escape" delimiter to escape HTML in data property values
  3619. * _.template('<b><%- value %></b>', { 'value': '<script>' });
  3620. * // => '<b>&lt;script&gt;</b>'
  3621. *
  3622. * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
  3623. * _.template('hello ${ name }', { 'name': 'curly' });
  3624. * // => 'hello curly'
  3625. *
  3626. * // using the internal `print` function in "evaluate" delimiters
  3627. * _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' });
  3628. * // => 'hello stooge!'
  3629. *
  3630. * // using custom template delimiters
  3631. * _.templateSettings = {
  3632. * 'interpolate': /{{([\s\S]+?)}}/g
  3633. * };
  3634. *
  3635. * _.template('hello {{ name }}!', { 'name': 'mustache' });
  3636. * // => 'hello mustache!'
  3637. *
  3638. * // using the `sourceURL` option to specify a custom sourceURL for the template
  3639. * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
  3640. * compiled(data);
  3641. * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
  3642. *
  3643. * // using the `variable` option to ensure a with-statement isn't used in the compiled template
  3644. * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
  3645. * compiled.source;
  3646. * // => function(data) {
  3647. * var __t, __p = '', __e = _.escape;
  3648. * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
  3649. * return __p;
  3650. * }
  3651. *
  3652. * // using the `source` property to inline compiled templates for meaningful
  3653. * // line numbers in error messages and a stack trace
  3654. * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
  3655. * var JST = {\
  3656. * "main": ' + _.template(mainText).source + '\
  3657. * };\
  3658. * ');
  3659. */
  3660. function template(text, data, options) {
  3661. text || (text = '');
  3662. options = defaults({}, options, lodash.templateSettings);
  3663. var index = 0,
  3664. source = "__p += '",
  3665. variable = options.variable;
  3666. var reDelimiters = RegExp(
  3667. (options.escape || reNoMatch).source + '|' +
  3668. (options.interpolate || reNoMatch).source + '|' +
  3669. (options.evaluate || reNoMatch).source + '|$'
  3670. , 'g');
  3671. text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {
  3672. source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
  3673. if (escapeValue) {
  3674. source += "' +\n_.escape(" + escapeValue + ") +\n'";
  3675. }
  3676. if (evaluateValue) {
  3677. source += "';\n" + evaluateValue + ";\n__p += '";
  3678. }
  3679. if (interpolateValue) {
  3680. source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
  3681. }
  3682. index = offset + match.length;
  3683. return match;
  3684. });
  3685. source += "';\n";
  3686. if (!variable) {
  3687. variable = 'obj';
  3688. source = 'with (' + variable + ' || {}) {\n' + source + '\n}\n';
  3689. }
  3690. source = 'function(' + variable + ') {\n' +
  3691. "var __t, __p = '', __j = Array.prototype.join;\n" +
  3692. "function print() { __p += __j.call(arguments, '') }\n" +
  3693. source +
  3694. 'return __p\n}';
  3695. try {
  3696. var result = Function('_', 'return ' + source)(lodash);
  3697. } catch(e) {
  3698. e.source = source;
  3699. throw e;
  3700. }
  3701. if (data) {
  3702. return result(data);
  3703. }
  3704. result.source = source;
  3705. return result;
  3706. }
  3707. /**
  3708. * Executes the `callback` function `n` times, returning an array of the results
  3709. * of each `callback` execution. The `callback` is bound to `thisArg` and invoked
  3710. * with one argument; (index).
  3711. *
  3712. * @static
  3713. * @memberOf _
  3714. * @category Utilities
  3715. * @param {Number} n The number of times to execute the callback.
  3716. * @param {Function} callback The function called per iteration.
  3717. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3718. * @returns {Array} Returns a new array of the results of each `callback` execution.
  3719. * @example
  3720. *
  3721. * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
  3722. * // => [3, 6, 4]
  3723. *
  3724. * _.times(3, function(n) { mage.castSpell(n); });
  3725. * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
  3726. *
  3727. * _.times(3, function(n) { this.cast(n); }, mage);
  3728. * // => also calls `mage.castSpell(n)` three times
  3729. */
  3730. function times(n, callback, thisArg) {
  3731. n = +n || 0;
  3732. var index = -1,
  3733. result = Array(n);
  3734. while (++index < n) {
  3735. result[index] = callback.call(thisArg, index);
  3736. }
  3737. return result;
  3738. }
  3739. /**
  3740. * The opposite of `_.escape`, this method converts the HTML entities
  3741. * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
  3742. * corresponding characters.
  3743. *
  3744. * @static
  3745. * @memberOf _
  3746. * @category Utilities
  3747. * @param {String} string The string to unescape.
  3748. * @returns {String} Returns the unescaped string.
  3749. * @example
  3750. *
  3751. * _.unescape('Moe, Larry &amp; Curly');
  3752. * // => 'Moe, Larry & Curly'
  3753. */
  3754. function unescape(string) {
  3755. return string == null ? '' : (string + '').replace(reEscapedHtml, unescapeHtmlChar);
  3756. }
  3757. /**
  3758. * Generates a unique ID. If `prefix` is passed, the ID will be appended to it.
  3759. *
  3760. * @static
  3761. * @memberOf _
  3762. * @category Utilities
  3763. * @param {String} [prefix] The value to prefix the ID with.
  3764. * @returns {String} Returns the unique ID.
  3765. * @example
  3766. *
  3767. * _.uniqueId('contact_');
  3768. * // => 'contact_104'
  3769. *
  3770. * _.uniqueId();
  3771. * // => '105'
  3772. */
  3773. function uniqueId(prefix) {
  3774. var id = ++idCounter + '';
  3775. return prefix ? prefix + id : id;
  3776. }
  3777. /*--------------------------------------------------------------------------*/
  3778. /**
  3779. * Creates a `lodash` object that wraps the given `value`.
  3780. *
  3781. * @static
  3782. * @memberOf _
  3783. * @category Chaining
  3784. * @param {Mixed} value The value to wrap.
  3785. * @returns {Object} Returns the wrapper object.
  3786. * @example
  3787. *
  3788. * var stooges = [
  3789. * { 'name': 'moe', 'age': 40 },
  3790. * { 'name': 'larry', 'age': 50 },
  3791. * { 'name': 'curly', 'age': 60 }
  3792. * ];
  3793. *
  3794. * var youngest = _.chain(stooges)
  3795. * .sortBy(function(stooge) { return stooge.age; })
  3796. * .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })
  3797. * .first();
  3798. * // => 'moe is 40'
  3799. */
  3800. function chain(value) {
  3801. value = new lodash(value);
  3802. value.__chain__ = true;
  3803. return value;
  3804. }
  3805. /**
  3806. * Invokes `interceptor` with the `value` as the first argument, and then
  3807. * returns `value`. The purpose of this method is to "tap into" a method chain,
  3808. * in order to perform operations on intermediate results within the chain.
  3809. *
  3810. * @static
  3811. * @memberOf _
  3812. * @category Chaining
  3813. * @param {Mixed} value The value to pass to `interceptor`.
  3814. * @param {Function} interceptor The function to invoke.
  3815. * @returns {Mixed} Returns `value`.
  3816. * @example
  3817. *
  3818. * _([1, 2, 3, 4])
  3819. * .filter(function(num) { return num % 2 == 0; })
  3820. * .tap(alert)
  3821. * .map(function(num) { return num * num; })
  3822. * .value();
  3823. * // => // [2, 4] (alerted)
  3824. * // => [4, 16]
  3825. */
  3826. function tap(value, interceptor) {
  3827. interceptor(value);
  3828. return value;
  3829. }
  3830. /**
  3831. * Enables method chaining on the wrapper object.
  3832. *
  3833. * @name chain
  3834. * @memberOf _
  3835. * @category Chaining
  3836. * @returns {Mixed} Returns the wrapper object.
  3837. * @example
  3838. *
  3839. * var sum = _([1, 2, 3])
  3840. * .chain()
  3841. * .reduce(function(sum, num) { return sum + num; })
  3842. * .value()
  3843. * // => 6`
  3844. */
  3845. function wrapperChain() {
  3846. this.__chain__ = true;
  3847. return this;
  3848. }
  3849. /**
  3850. * Produces the `toString` result of the wrapped value.
  3851. *
  3852. * @name toString
  3853. * @memberOf _
  3854. * @category Chaining
  3855. * @returns {String} Returns the string result.
  3856. * @example
  3857. *
  3858. * _([1, 2, 3]).toString();
  3859. * // => '1,2,3'
  3860. */
  3861. function wrapperToString() {
  3862. return this.__wrapped__ + '';
  3863. }
  3864. /**
  3865. * Extracts the wrapped value.
  3866. *
  3867. * @name valueOf
  3868. * @memberOf _
  3869. * @alias value
  3870. * @category Chaining
  3871. * @returns {Mixed} Returns the wrapped value.
  3872. * @example
  3873. *
  3874. * _([1, 2, 3]).valueOf();
  3875. * // => [1, 2, 3]
  3876. */
  3877. function wrapperValueOf() {
  3878. return this.__wrapped__;
  3879. }
  3880. /*--------------------------------------------------------------------------*/
  3881. // add functions that return wrapped values when chaining
  3882. lodash.after = after;
  3883. lodash.bind = bind;
  3884. lodash.bindAll = bindAll;
  3885. lodash.compact = compact;
  3886. lodash.compose = compose;
  3887. lodash.countBy = countBy;
  3888. lodash.debounce = debounce;
  3889. lodash.defaults = defaults;
  3890. lodash.defer = defer;
  3891. lodash.delay = delay;
  3892. lodash.difference = difference;
  3893. lodash.filter = filter;
  3894. lodash.flatten = flatten;
  3895. lodash.forEach = forEach;
  3896. lodash.functions = functions;
  3897. lodash.groupBy = groupBy;
  3898. lodash.initial = initial;
  3899. lodash.intersection = intersection;
  3900. lodash.invert = invert;
  3901. lodash.invoke = invoke;
  3902. lodash.keys = keys;
  3903. lodash.map = map;
  3904. lodash.max = max;
  3905. lodash.memoize = memoize;
  3906. lodash.min = min;
  3907. lodash.object = object;
  3908. lodash.omit = omit;
  3909. lodash.once = once;
  3910. lodash.pairs = pairs;
  3911. lodash.partial = partial;
  3912. lodash.pick = pick;
  3913. lodash.pluck = pluck;
  3914. lodash.range = range;
  3915. lodash.reject = reject;
  3916. lodash.rest = rest;
  3917. lodash.shuffle = shuffle;
  3918. lodash.sortBy = sortBy;
  3919. lodash.tap = tap;
  3920. lodash.throttle = throttle;
  3921. lodash.times = times;
  3922. lodash.toArray = toArray;
  3923. lodash.union = union;
  3924. lodash.uniq = uniq;
  3925. lodash.values = values;
  3926. lodash.where = where;
  3927. lodash.without = without;
  3928. lodash.wrap = wrap;
  3929. lodash.zip = zip;
  3930. // add aliases
  3931. lodash.collect = map;
  3932. lodash.drop = rest;
  3933. lodash.each = forEach;
  3934. lodash.extend = assign;
  3935. lodash.methods = functions;
  3936. lodash.select = filter;
  3937. lodash.tail = rest;
  3938. lodash.unique = uniq;
  3939. /*--------------------------------------------------------------------------*/
  3940. // add functions that return unwrapped values when chaining
  3941. lodash.clone = clone;
  3942. lodash.contains = contains;
  3943. lodash.escape = escape;
  3944. lodash.every = every;
  3945. lodash.find = find;
  3946. lodash.findWhere = findWhere;
  3947. lodash.has = has;
  3948. lodash.identity = identity;
  3949. lodash.indexOf = indexOf;
  3950. lodash.isArguments = isArguments;
  3951. lodash.isArray = isArray;
  3952. lodash.isBoolean = isBoolean;
  3953. lodash.isDate = isDate;
  3954. lodash.isElement = isElement;
  3955. lodash.isEmpty = isEmpty;
  3956. lodash.isEqual = isEqual;
  3957. lodash.isFinite = isFinite;
  3958. lodash.isFunction = isFunction;
  3959. lodash.isNaN = isNaN;
  3960. lodash.isNull = isNull;
  3961. lodash.isNumber = isNumber;
  3962. lodash.isObject = isObject;
  3963. lodash.isRegExp = isRegExp;
  3964. lodash.isString = isString;
  3965. lodash.isUndefined = isUndefined;
  3966. lodash.lastIndexOf = lastIndexOf;
  3967. lodash.mixin = mixin;
  3968. lodash.noConflict = noConflict;
  3969. lodash.random = random;
  3970. lodash.reduce = reduce;
  3971. lodash.reduceRight = reduceRight;
  3972. lodash.result = result;
  3973. lodash.size = size;
  3974. lodash.some = some;
  3975. lodash.sortedIndex = sortedIndex;
  3976. lodash.template = template;
  3977. lodash.unescape = unescape;
  3978. lodash.uniqueId = uniqueId;
  3979. // add aliases
  3980. lodash.all = every;
  3981. lodash.any = some;
  3982. lodash.detect = find;
  3983. lodash.foldl = reduce;
  3984. lodash.foldr = reduceRight;
  3985. lodash.include = contains;
  3986. lodash.inject = reduce;
  3987. /*--------------------------------------------------------------------------*/
  3988. // add functions capable of returning wrapped and unwrapped values when chaining
  3989. lodash.first = first;
  3990. lodash.last = last;
  3991. // add aliases
  3992. lodash.take = first;
  3993. lodash.head = first;
  3994. /*--------------------------------------------------------------------------*/
  3995. lodash.chain = chain;
  3996. /**
  3997. * The semantic version number.
  3998. *
  3999. * @static
  4000. * @memberOf _
  4001. * @type String
  4002. */
  4003. lodash.VERSION = '1.0.2';
  4004. // add functions to `lodash.prototype`
  4005. mixin(lodash);
  4006. // add "Chaining" functions to the wrapper
  4007. lodash.prototype.chain = wrapperChain;
  4008. lodash.prototype.value = wrapperValueOf;
  4009. // add `Array` mutator functions to the wrapper
  4010. each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
  4011. var func = arrayRef[methodName];
  4012. lodash.prototype[methodName] = function() {
  4013. var value = this.__wrapped__;
  4014. func.apply(value, arguments);
  4015. // avoid array-like object bugs with `Array#shift` and `Array#splice`
  4016. // in Firefox < 10 and IE < 9
  4017. if (hasObjectSpliceBug && value.length === 0) {
  4018. delete value[0];
  4019. }
  4020. return this;
  4021. };
  4022. });
  4023. // add `Array` accessor functions to the wrapper
  4024. each(['concat', 'join', 'slice'], function(methodName) {
  4025. var func = arrayRef[methodName];
  4026. lodash.prototype[methodName] = function() {
  4027. var value = this.__wrapped__,
  4028. result = func.apply(value, arguments);
  4029. if (this.__chain__) {
  4030. result = new lodash(result);
  4031. result.__chain__ = true;
  4032. }
  4033. return result;
  4034. };
  4035. });
  4036. /*--------------------------------------------------------------------------*/
  4037. if (freeExports) {
  4038. // in Node.js or RingoJS v0.8.0+
  4039. if (freeModule) {
  4040. (freeModule.exports = lodash)._ = lodash;
  4041. }
  4042. // in Narwhal or RingoJS v0.7.0-
  4043. else {
  4044. freeExports._ = lodash;
  4045. }
  4046. }
  4047. else {
  4048. // in a browser or Rhino
  4049. window._ = lodash;
  4050. }
  4051. }(this));