lodash.js 156 KB

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