lodash.underscore.js 110 KB

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