lodash.underscore.js 117 KB

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