lodash-copy.js 133 KB

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