| OLD | NEW |
| (Empty) | |
| 1 /** |
| 2 * @license |
| 3 * lodash 3.10.1 (Custom Build) <https://lodash.com/> |
| 4 * Build: `lodash modern -o ./lodash.js` |
| 5 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/> |
| 6 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> |
| 7 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporter
s & Editors |
| 8 * Available under MIT license <https://lodash.com/license> |
| 9 */ |
| 10 ;(function() { |
| 11 |
| 12 /** Used as a safe reference for `undefined` in pre-ES5 environments. */ |
| 13 var undefined; |
| 14 |
| 15 /** Used as the semantic version number. */ |
| 16 var VERSION = '3.10.1'; |
| 17 |
| 18 /** Used to compose bitmasks for wrapper metadata. */ |
| 19 var BIND_FLAG = 1, |
| 20 BIND_KEY_FLAG = 2, |
| 21 CURRY_BOUND_FLAG = 4, |
| 22 CURRY_FLAG = 8, |
| 23 CURRY_RIGHT_FLAG = 16, |
| 24 PARTIAL_FLAG = 32, |
| 25 PARTIAL_RIGHT_FLAG = 64, |
| 26 ARY_FLAG = 128, |
| 27 REARG_FLAG = 256; |
| 28 |
| 29 /** Used as default options for `_.trunc`. */ |
| 30 var DEFAULT_TRUNC_LENGTH = 30, |
| 31 DEFAULT_TRUNC_OMISSION = '...'; |
| 32 |
| 33 /** Used to detect when a function becomes hot. */ |
| 34 var HOT_COUNT = 150, |
| 35 HOT_SPAN = 16; |
| 36 |
| 37 /** Used as the size to enable large array optimizations. */ |
| 38 var LARGE_ARRAY_SIZE = 200; |
| 39 |
| 40 /** Used to indicate the type of lazy iteratees. */ |
| 41 var LAZY_FILTER_FLAG = 1, |
| 42 LAZY_MAP_FLAG = 2; |
| 43 |
| 44 /** Used as the `TypeError` message for "Functions" methods. */ |
| 45 var FUNC_ERROR_TEXT = 'Expected a function'; |
| 46 |
| 47 /** Used as the internal argument placeholder. */ |
| 48 var PLACEHOLDER = '__lodash_placeholder__'; |
| 49 |
| 50 /** `Object#toString` result references. */ |
| 51 var argsTag = '[object Arguments]', |
| 52 arrayTag = '[object Array]', |
| 53 boolTag = '[object Boolean]', |
| 54 dateTag = '[object Date]', |
| 55 errorTag = '[object Error]', |
| 56 funcTag = '[object Function]', |
| 57 mapTag = '[object Map]', |
| 58 numberTag = '[object Number]', |
| 59 objectTag = '[object Object]', |
| 60 regexpTag = '[object RegExp]', |
| 61 setTag = '[object Set]', |
| 62 stringTag = '[object String]', |
| 63 weakMapTag = '[object WeakMap]'; |
| 64 |
| 65 var arrayBufferTag = '[object ArrayBuffer]', |
| 66 float32Tag = '[object Float32Array]', |
| 67 float64Tag = '[object Float64Array]', |
| 68 int8Tag = '[object Int8Array]', |
| 69 int16Tag = '[object Int16Array]', |
| 70 int32Tag = '[object Int32Array]', |
| 71 uint8Tag = '[object Uint8Array]', |
| 72 uint8ClampedTag = '[object Uint8ClampedArray]', |
| 73 uint16Tag = '[object Uint16Array]', |
| 74 uint32Tag = '[object Uint32Array]'; |
| 75 |
| 76 /** Used to match empty string literals in compiled template source. */ |
| 77 var reEmptyStringLeading = /\b__p \+= '';/g, |
| 78 reEmptyStringMiddle = /\b(__p \+=) '' \+/g, |
| 79 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; |
| 80 |
| 81 /** Used to match HTML entities and HTML characters. */ |
| 82 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, |
| 83 reUnescapedHtml = /[&<>"'`]/g, |
| 84 reHasEscapedHtml = RegExp(reEscapedHtml.source), |
| 85 reHasUnescapedHtml = RegExp(reUnescapedHtml.source); |
| 86 |
| 87 /** Used to match template delimiters. */ |
| 88 var reEscape = /<%-([\s\S]+?)%>/g, |
| 89 reEvaluate = /<%([\s\S]+?)%>/g, |
| 90 reInterpolate = /<%=([\s\S]+?)%>/g; |
| 91 |
| 92 /** Used to match property names within property paths. */ |
| 93 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, |
| 94 reIsPlainProp = /^\w*$/, |
| 95 rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)
*?)\2)\]/g; |
| 96 |
| 97 /** |
| 98 * Used to match `RegExp` [syntax characters](http://ecma-international.org/ec
ma-262/6.0/#sec-patterns) |
| 99 * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org
/ecma-262/6.0/#sec-escaperegexppattern). |
| 100 */ |
| 101 var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u
2028\u2029])/g, |
| 102 reHasRegExpChars = RegExp(reRegExpChars.source); |
| 103 |
| 104 /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/
Combining_Diacritical_Marks). */ |
| 105 var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; |
| 106 |
| 107 /** Used to match backslashes in property paths. */ |
| 108 var reEscapeChar = /\\(\\)?/g; |
| 109 |
| 110 /** Used to match [ES template delimiters](http://ecma-international.org/ecma-
262/6.0/#sec-template-literal-lexical-components). */ |
| 111 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; |
| 112 |
| 113 /** Used to match `RegExp` flags from their coerced string values. */ |
| 114 var reFlags = /\w*$/; |
| 115 |
| 116 /** Used to detect hexadecimal string values. */ |
| 117 var reHasHexPrefix = /^0[xX]/; |
| 118 |
| 119 /** Used to detect host constructors (Safari > 5). */ |
| 120 var reIsHostCtor = /^\[object .+?Constructor\]$/; |
| 121 |
| 122 /** Used to detect unsigned integer values. */ |
| 123 var reIsUint = /^\d+$/; |
| 124 |
| 125 /** Used to match latin-1 supplementary letters (excluding mathematical operat
ors). */ |
| 126 var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; |
| 127 |
| 128 /** Used to ensure capturing order of template delimiters. */ |
| 129 var reNoMatch = /($^)/; |
| 130 |
| 131 /** Used to match unescaped characters in compiled string literals. */ |
| 132 var reUnescapedString = /['\n\r\u2028\u2029\\]/g; |
| 133 |
| 134 /** Used to match words to create compound words. */ |
| 135 var reWords = (function() { |
| 136 var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', |
| 137 lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; |
| 138 |
| 139 return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower +
'|' + upper + '+|[0-9]+', 'g'); |
| 140 }()); |
| 141 |
| 142 /** Used to assign default `context` object properties. */ |
| 143 var contextProps = [ |
| 144 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', |
| 145 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', |
| 146 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', |
| 147 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', |
| 148 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' |
| 149 ]; |
| 150 |
| 151 /** Used to make template sourceURLs easier to identify. */ |
| 152 var templateCounter = -1; |
| 153 |
| 154 /** Used to identify `toStringTag` values of typed arrays. */ |
| 155 var typedArrayTags = {}; |
| 156 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = |
| 157 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = |
| 158 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = |
| 159 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = |
| 160 typedArrayTags[uint32Tag] = true; |
| 161 typedArrayTags[argsTag] = typedArrayTags[arrayTag] = |
| 162 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = |
| 163 typedArrayTags[dateTag] = typedArrayTags[errorTag] = |
| 164 typedArrayTags[funcTag] = typedArrayTags[mapTag] = |
| 165 typedArrayTags[numberTag] = typedArrayTags[objectTag] = |
| 166 typedArrayTags[regexpTag] = typedArrayTags[setTag] = |
| 167 typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; |
| 168 |
| 169 /** Used to identify `toStringTag` values supported by `_.clone`. */ |
| 170 var cloneableTags = {}; |
| 171 cloneableTags[argsTag] = cloneableTags[arrayTag] = |
| 172 cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = |
| 173 cloneableTags[dateTag] = cloneableTags[float32Tag] = |
| 174 cloneableTags[float64Tag] = cloneableTags[int8Tag] = |
| 175 cloneableTags[int16Tag] = cloneableTags[int32Tag] = |
| 176 cloneableTags[numberTag] = cloneableTags[objectTag] = |
| 177 cloneableTags[regexpTag] = cloneableTags[stringTag] = |
| 178 cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = |
| 179 cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; |
| 180 cloneableTags[errorTag] = cloneableTags[funcTag] = |
| 181 cloneableTags[mapTag] = cloneableTags[setTag] = |
| 182 cloneableTags[weakMapTag] = false; |
| 183 |
| 184 /** Used to map latin-1 supplementary letters to basic latin letters. */ |
| 185 var deburredLetters = { |
| 186 '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A
', |
| 187 '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a
', |
| 188 '\xc7': 'C', '\xe7': 'c', |
| 189 '\xd0': 'D', '\xf0': 'd', |
| 190 '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', |
| 191 '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', |
| 192 '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', |
| 193 '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', |
| 194 '\xd1': 'N', '\xf1': 'n', |
| 195 '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O
', |
| 196 '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o
', |
| 197 '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', |
| 198 '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', |
| 199 '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', |
| 200 '\xc6': 'Ae', '\xe6': 'ae', |
| 201 '\xde': 'Th', '\xfe': 'th', |
| 202 '\xdf': 'ss' |
| 203 }; |
| 204 |
| 205 /** Used to map characters to HTML entities. */ |
| 206 var htmlEscapes = { |
| 207 '&': '&', |
| 208 '<': '<', |
| 209 '>': '>', |
| 210 '"': '"', |
| 211 "'": ''', |
| 212 '`': '`' |
| 213 }; |
| 214 |
| 215 /** Used to map HTML entities to characters. */ |
| 216 var htmlUnescapes = { |
| 217 '&': '&', |
| 218 '<': '<', |
| 219 '>': '>', |
| 220 '"': '"', |
| 221 ''': "'", |
| 222 '`': '`' |
| 223 }; |
| 224 |
| 225 /** Used to determine if values are of the language type `Object`. */ |
| 226 var objectTypes = { |
| 227 'function': true, |
| 228 'object': true |
| 229 }; |
| 230 |
| 231 /** Used to escape characters for inclusion in compiled regexes. */ |
| 232 var regexpEscapes = { |
| 233 '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', |
| 234 '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', |
| 235 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', |
| 236 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', |
| 237 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' |
| 238 }; |
| 239 |
| 240 /** Used to escape characters for inclusion in compiled string literals. */ |
| 241 var stringEscapes = { |
| 242 '\\': '\\', |
| 243 "'": "'", |
| 244 '\n': 'n', |
| 245 '\r': 'r', |
| 246 '\u2028': 'u2028', |
| 247 '\u2029': 'u2029' |
| 248 }; |
| 249 |
| 250 /** Detect free variable `exports`. */ |
| 251 var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType
&& exports; |
| 252 |
| 253 /** Detect free variable `module`. */ |
| 254 var freeModule = objectTypes[typeof module] && module && !module.nodeType && m
odule; |
| 255 |
| 256 /** Detect free variable `global` from Node.js. */ |
| 257 var freeGlobal = freeExports && freeModule && typeof global == 'object' && glo
bal && global.Object && global; |
| 258 |
| 259 /** Detect free variable `self`. */ |
| 260 var freeSelf = objectTypes[typeof self] && self && self.Object && self; |
| 261 |
| 262 /** Detect free variable `window`. */ |
| 263 var freeWindow = objectTypes[typeof window] && window && window.Object && wind
ow; |
| 264 |
| 265 /** Detect the popular CommonJS extension `module.exports`. */ |
| 266 var moduleExports = freeModule && freeModule.exports === freeExports && freeEx
ports; |
| 267 |
| 268 /** |
| 269 * Used as a reference to the global object. |
| 270 * |
| 271 * The `this` value is used if it's the global object to avoid Greasemonkey's |
| 272 * restricted `window` object, otherwise the `window` object is used. |
| 273 */ |
| 274 var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow
) || freeSelf || this; |
| 275 |
| 276 /*--------------------------------------------------------------------------*/ |
| 277 |
| 278 /** |
| 279 * The base implementation of `compareAscending` which compares values and |
| 280 * sorts them in ascending order without guaranteeing a stable sort. |
| 281 * |
| 282 * @private |
| 283 * @param {*} value The value to compare. |
| 284 * @param {*} other The other value to compare. |
| 285 * @returns {number} Returns the sort order indicator for `value`. |
| 286 */ |
| 287 function baseCompareAscending(value, other) { |
| 288 if (value !== other) { |
| 289 var valIsNull = value === null, |
| 290 valIsUndef = value === undefined, |
| 291 valIsReflexive = value === value; |
| 292 |
| 293 var othIsNull = other === null, |
| 294 othIsUndef = other === undefined, |
| 295 othIsReflexive = other === other; |
| 296 |
| 297 if ((value > other && !othIsNull) || !valIsReflexive || |
| 298 (valIsNull && !othIsUndef && othIsReflexive) || |
| 299 (valIsUndef && othIsReflexive)) { |
| 300 return 1; |
| 301 } |
| 302 if ((value < other && !valIsNull) || !othIsReflexive || |
| 303 (othIsNull && !valIsUndef && valIsReflexive) || |
| 304 (othIsUndef && valIsReflexive)) { |
| 305 return -1; |
| 306 } |
| 307 } |
| 308 return 0; |
| 309 } |
| 310 |
| 311 /** |
| 312 * The base implementation of `_.findIndex` and `_.findLastIndex` without |
| 313 * support for callback shorthands and `this` binding. |
| 314 * |
| 315 * @private |
| 316 * @param {Array} array The array to search. |
| 317 * @param {Function} predicate The function invoked per iteration. |
| 318 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 319 * @returns {number} Returns the index of the matched value, else `-1`. |
| 320 */ |
| 321 function baseFindIndex(array, predicate, fromRight) { |
| 322 var length = array.length, |
| 323 index = fromRight ? length : -1; |
| 324 |
| 325 while ((fromRight ? index-- : ++index < length)) { |
| 326 if (predicate(array[index], index, array)) { |
| 327 return index; |
| 328 } |
| 329 } |
| 330 return -1; |
| 331 } |
| 332 |
| 333 /** |
| 334 * The base implementation of `_.indexOf` without support for binary searches. |
| 335 * |
| 336 * @private |
| 337 * @param {Array} array The array to search. |
| 338 * @param {*} value The value to search for. |
| 339 * @param {number} fromIndex The index to search from. |
| 340 * @returns {number} Returns the index of the matched value, else `-1`. |
| 341 */ |
| 342 function baseIndexOf(array, value, fromIndex) { |
| 343 if (value !== value) { |
| 344 return indexOfNaN(array, fromIndex); |
| 345 } |
| 346 var index = fromIndex - 1, |
| 347 length = array.length; |
| 348 |
| 349 while (++index < length) { |
| 350 if (array[index] === value) { |
| 351 return index; |
| 352 } |
| 353 } |
| 354 return -1; |
| 355 } |
| 356 |
| 357 /** |
| 358 * The base implementation of `_.isFunction` without support for environments |
| 359 * with incorrect `typeof` results. |
| 360 * |
| 361 * @private |
| 362 * @param {*} value The value to check. |
| 363 * @returns {boolean} Returns `true` if `value` is correctly classified, else
`false`. |
| 364 */ |
| 365 function baseIsFunction(value) { |
| 366 // Avoid a Chakra JIT bug in compatibility modes of IE 11. |
| 367 // See https://github.com/jashkenas/underscore/issues/1621 for more details. |
| 368 return typeof value == 'function' || false; |
| 369 } |
| 370 |
| 371 /** |
| 372 * Converts `value` to a string if it's not one. An empty string is returned |
| 373 * for `null` or `undefined` values. |
| 374 * |
| 375 * @private |
| 376 * @param {*} value The value to process. |
| 377 * @returns {string} Returns the string. |
| 378 */ |
| 379 function baseToString(value) { |
| 380 return value == null ? '' : (value + ''); |
| 381 } |
| 382 |
| 383 /** |
| 384 * Used by `_.trim` and `_.trimLeft` to get the index of the first character |
| 385 * of `string` that is not found in `chars`. |
| 386 * |
| 387 * @private |
| 388 * @param {string} string The string to inspect. |
| 389 * @param {string} chars The characters to find. |
| 390 * @returns {number} Returns the index of the first character not found in `ch
ars`. |
| 391 */ |
| 392 function charsLeftIndex(string, chars) { |
| 393 var index = -1, |
| 394 length = string.length; |
| 395 |
| 396 while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} |
| 397 return index; |
| 398 } |
| 399 |
| 400 /** |
| 401 * Used by `_.trim` and `_.trimRight` to get the index of the last character |
| 402 * of `string` that is not found in `chars`. |
| 403 * |
| 404 * @private |
| 405 * @param {string} string The string to inspect. |
| 406 * @param {string} chars The characters to find. |
| 407 * @returns {number} Returns the index of the last character not found in `cha
rs`. |
| 408 */ |
| 409 function charsRightIndex(string, chars) { |
| 410 var index = string.length; |
| 411 |
| 412 while (index-- && chars.indexOf(string.charAt(index)) > -1) {} |
| 413 return index; |
| 414 } |
| 415 |
| 416 /** |
| 417 * Used by `_.sortBy` to compare transformed elements of a collection and stab
le |
| 418 * sort them in ascending order. |
| 419 * |
| 420 * @private |
| 421 * @param {Object} object The object to compare. |
| 422 * @param {Object} other The other object to compare. |
| 423 * @returns {number} Returns the sort order indicator for `object`. |
| 424 */ |
| 425 function compareAscending(object, other) { |
| 426 return baseCompareAscending(object.criteria, other.criteria) || (object.inde
x - other.index); |
| 427 } |
| 428 |
| 429 /** |
| 430 * Used by `_.sortByOrder` to compare multiple properties of a value to anothe
r |
| 431 * and stable sort them. |
| 432 * |
| 433 * If `orders` is unspecified, all valuess are sorted in ascending order. Othe
rwise, |
| 434 * a value is sorted in ascending order if its corresponding order is "asc", a
nd |
| 435 * descending if "desc". |
| 436 * |
| 437 * @private |
| 438 * @param {Object} object The object to compare. |
| 439 * @param {Object} other The other object to compare. |
| 440 * @param {boolean[]} orders The order to sort by for each property. |
| 441 * @returns {number} Returns the sort order indicator for `object`. |
| 442 */ |
| 443 function compareMultiple(object, other, orders) { |
| 444 var index = -1, |
| 445 objCriteria = object.criteria, |
| 446 othCriteria = other.criteria, |
| 447 length = objCriteria.length, |
| 448 ordersLength = orders.length; |
| 449 |
| 450 while (++index < length) { |
| 451 var result = baseCompareAscending(objCriteria[index], othCriteria[index]); |
| 452 if (result) { |
| 453 if (index >= ordersLength) { |
| 454 return result; |
| 455 } |
| 456 var order = orders[index]; |
| 457 return result * ((order === 'asc' || order === true) ? 1 : -1); |
| 458 } |
| 459 } |
| 460 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications |
| 461 // that causes it, under certain circumstances, to provide the same value fo
r |
| 462 // `object` and `other`. See https://github.com/jashkenas/underscore/pull/12
47 |
| 463 // for more details. |
| 464 // |
| 465 // This also ensures a stable sort in V8 and other engines. |
| 466 // See https://code.google.com/p/v8/issues/detail?id=90 for more details. |
| 467 return object.index - other.index; |
| 468 } |
| 469 |
| 470 /** |
| 471 * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin
letters. |
| 472 * |
| 473 * @private |
| 474 * @param {string} letter The matched letter to deburr. |
| 475 * @returns {string} Returns the deburred letter. |
| 476 */ |
| 477 function deburrLetter(letter) { |
| 478 return deburredLetters[letter]; |
| 479 } |
| 480 |
| 481 /** |
| 482 * Used by `_.escape` to convert characters to HTML entities. |
| 483 * |
| 484 * @private |
| 485 * @param {string} chr The matched character to escape. |
| 486 * @returns {string} Returns the escaped character. |
| 487 */ |
| 488 function escapeHtmlChar(chr) { |
| 489 return htmlEscapes[chr]; |
| 490 } |
| 491 |
| 492 /** |
| 493 * Used by `_.escapeRegExp` to escape characters for inclusion in compiled reg
exes. |
| 494 * |
| 495 * @private |
| 496 * @param {string} chr The matched character to escape. |
| 497 * @param {string} leadingChar The capture group for a leading character. |
| 498 * @param {string} whitespaceChar The capture group for a whitespace character
. |
| 499 * @returns {string} Returns the escaped character. |
| 500 */ |
| 501 function escapeRegExpChar(chr, leadingChar, whitespaceChar) { |
| 502 if (leadingChar) { |
| 503 chr = regexpEscapes[chr]; |
| 504 } else if (whitespaceChar) { |
| 505 chr = stringEscapes[chr]; |
| 506 } |
| 507 return '\\' + chr; |
| 508 } |
| 509 |
| 510 /** |
| 511 * Used by `_.template` to escape characters for inclusion in compiled string
literals. |
| 512 * |
| 513 * @private |
| 514 * @param {string} chr The matched character to escape. |
| 515 * @returns {string} Returns the escaped character. |
| 516 */ |
| 517 function escapeStringChar(chr) { |
| 518 return '\\' + stringEscapes[chr]; |
| 519 } |
| 520 |
| 521 /** |
| 522 * Gets the index at which the first occurrence of `NaN` is found in `array`. |
| 523 * |
| 524 * @private |
| 525 * @param {Array} array The array to search. |
| 526 * @param {number} fromIndex The index to search from. |
| 527 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 528 * @returns {number} Returns the index of the matched `NaN`, else `-1`. |
| 529 */ |
| 530 function indexOfNaN(array, fromIndex, fromRight) { |
| 531 var length = array.length, |
| 532 index = fromIndex + (fromRight ? 0 : -1); |
| 533 |
| 534 while ((fromRight ? index-- : ++index < length)) { |
| 535 var other = array[index]; |
| 536 if (other !== other) { |
| 537 return index; |
| 538 } |
| 539 } |
| 540 return -1; |
| 541 } |
| 542 |
| 543 /** |
| 544 * Checks if `value` is object-like. |
| 545 * |
| 546 * @private |
| 547 * @param {*} value The value to check. |
| 548 * @returns {boolean} Returns `true` if `value` is object-like, else `false`. |
| 549 */ |
| 550 function isObjectLike(value) { |
| 551 return !!value && typeof value == 'object'; |
| 552 } |
| 553 |
| 554 /** |
| 555 * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a |
| 556 * character code is whitespace. |
| 557 * |
| 558 * @private |
| 559 * @param {number} charCode The character code to inspect. |
| 560 * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`
. |
| 561 */ |
| 562 function isSpace(charCode) { |
| 563 return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode ==
32 || charCode == 160) || charCode == 5760 || charCode == 6158 || |
| 564 (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode ==
8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode ==
65279))); |
| 565 } |
| 566 |
| 567 /** |
| 568 * Replaces all `placeholder` elements in `array` with an internal placeholder |
| 569 * and returns an array of their indexes. |
| 570 * |
| 571 * @private |
| 572 * @param {Array} array The array to modify. |
| 573 * @param {*} placeholder The placeholder to replace. |
| 574 * @returns {Array} Returns the new array of placeholder indexes. |
| 575 */ |
| 576 function replaceHolders(array, placeholder) { |
| 577 var index = -1, |
| 578 length = array.length, |
| 579 resIndex = -1, |
| 580 result = []; |
| 581 |
| 582 while (++index < length) { |
| 583 if (array[index] === placeholder) { |
| 584 array[index] = PLACEHOLDER; |
| 585 result[++resIndex] = index; |
| 586 } |
| 587 } |
| 588 return result; |
| 589 } |
| 590 |
| 591 /** |
| 592 * An implementation of `_.uniq` optimized for sorted arrays without support |
| 593 * for callback shorthands and `this` binding. |
| 594 * |
| 595 * @private |
| 596 * @param {Array} array The array to inspect. |
| 597 * @param {Function} [iteratee] The function invoked per iteration. |
| 598 * @returns {Array} Returns the new duplicate free array. |
| 599 */ |
| 600 function sortedUniq(array, iteratee) { |
| 601 var seen, |
| 602 index = -1, |
| 603 length = array.length, |
| 604 resIndex = -1, |
| 605 result = []; |
| 606 |
| 607 while (++index < length) { |
| 608 var value = array[index], |
| 609 computed = iteratee ? iteratee(value, index, array) : value; |
| 610 |
| 611 if (!index || seen !== computed) { |
| 612 seen = computed; |
| 613 result[++resIndex] = value; |
| 614 } |
| 615 } |
| 616 return result; |
| 617 } |
| 618 |
| 619 /** |
| 620 * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitesp
ace |
| 621 * character of `string`. |
| 622 * |
| 623 * @private |
| 624 * @param {string} string The string to inspect. |
| 625 * @returns {number} Returns the index of the first non-whitespace character. |
| 626 */ |
| 627 function trimmedLeftIndex(string) { |
| 628 var index = -1, |
| 629 length = string.length; |
| 630 |
| 631 while (++index < length && isSpace(string.charCodeAt(index))) {} |
| 632 return index; |
| 633 } |
| 634 |
| 635 /** |
| 636 * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitesp
ace |
| 637 * character of `string`. |
| 638 * |
| 639 * @private |
| 640 * @param {string} string The string to inspect. |
| 641 * @returns {number} Returns the index of the last non-whitespace character. |
| 642 */ |
| 643 function trimmedRightIndex(string) { |
| 644 var index = string.length; |
| 645 |
| 646 while (index-- && isSpace(string.charCodeAt(index))) {} |
| 647 return index; |
| 648 } |
| 649 |
| 650 /** |
| 651 * Used by `_.unescape` to convert HTML entities to characters. |
| 652 * |
| 653 * @private |
| 654 * @param {string} chr The matched character to unescape. |
| 655 * @returns {string} Returns the unescaped character. |
| 656 */ |
| 657 function unescapeHtmlChar(chr) { |
| 658 return htmlUnescapes[chr]; |
| 659 } |
| 660 |
| 661 /*--------------------------------------------------------------------------*/ |
| 662 |
| 663 /** |
| 664 * Create a new pristine `lodash` function using the given `context` object. |
| 665 * |
| 666 * @static |
| 667 * @memberOf _ |
| 668 * @category Utility |
| 669 * @param {Object} [context=root] The context object. |
| 670 * @returns {Function} Returns a new `lodash` function. |
| 671 * @example |
| 672 * |
| 673 * _.mixin({ 'foo': _.constant('foo') }); |
| 674 * |
| 675 * var lodash = _.runInContext(); |
| 676 * lodash.mixin({ 'bar': lodash.constant('bar') }); |
| 677 * |
| 678 * _.isFunction(_.foo); |
| 679 * // => true |
| 680 * _.isFunction(_.bar); |
| 681 * // => false |
| 682 * |
| 683 * lodash.isFunction(lodash.foo); |
| 684 * // => false |
| 685 * lodash.isFunction(lodash.bar); |
| 686 * // => true |
| 687 * |
| 688 * // using `context` to mock `Date#getTime` use in `_.now` |
| 689 * var mock = _.runInContext({ |
| 690 * 'Date': function() { |
| 691 * return { 'getTime': getTimeMock }; |
| 692 * } |
| 693 * }); |
| 694 * |
| 695 * // or creating a suped-up `defer` in Node.js |
| 696 * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; |
| 697 */ |
| 698 function runInContext(context) { |
| 699 // Avoid issues with some ES3 environments that attempt to use values, named |
| 700 // after built-in constructors like `Object`, for the creation of literals. |
| 701 // ES5 clears this up by stating that literals must use built-in constructor
s. |
| 702 // See https://es5.github.io/#x11.1.5 for more details. |
| 703 context = context ? _.defaults(root.Object(), context, _.pick(root, contextP
rops)) : root; |
| 704 |
| 705 /** Native constructor references. */ |
| 706 var Array = context.Array, |
| 707 Date = context.Date, |
| 708 Error = context.Error, |
| 709 Function = context.Function, |
| 710 Math = context.Math, |
| 711 Number = context.Number, |
| 712 Object = context.Object, |
| 713 RegExp = context.RegExp, |
| 714 String = context.String, |
| 715 TypeError = context.TypeError; |
| 716 |
| 717 /** Used for native method references. */ |
| 718 var arrayProto = Array.prototype, |
| 719 objectProto = Object.prototype, |
| 720 stringProto = String.prototype; |
| 721 |
| 722 /** Used to resolve the decompiled source of functions. */ |
| 723 var fnToString = Function.prototype.toString; |
| 724 |
| 725 /** Used to check objects for own properties. */ |
| 726 var hasOwnProperty = objectProto.hasOwnProperty; |
| 727 |
| 728 /** Used to generate unique IDs. */ |
| 729 var idCounter = 0; |
| 730 |
| 731 /** |
| 732 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-26
2/6.0/#sec-object.prototype.tostring) |
| 733 * of values. |
| 734 */ |
| 735 var objToString = objectProto.toString; |
| 736 |
| 737 /** Used to restore the original `_` reference in `_.noConflict`. */ |
| 738 var oldDash = root._; |
| 739 |
| 740 /** Used to detect if a method is native. */ |
| 741 var reIsNative = RegExp('^' + |
| 742 fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') |
| 743 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?'
) + '$' |
| 744 ); |
| 745 |
| 746 /** Native method references. */ |
| 747 var ArrayBuffer = context.ArrayBuffer, |
| 748 clearTimeout = context.clearTimeout, |
| 749 parseFloat = context.parseFloat, |
| 750 pow = Math.pow, |
| 751 propertyIsEnumerable = objectProto.propertyIsEnumerable, |
| 752 Set = getNative(context, 'Set'), |
| 753 setTimeout = context.setTimeout, |
| 754 splice = arrayProto.splice, |
| 755 Uint8Array = context.Uint8Array, |
| 756 WeakMap = getNative(context, 'WeakMap'); |
| 757 |
| 758 /* Native method references for those with the same name as other `lodash` m
ethods. */ |
| 759 var nativeCeil = Math.ceil, |
| 760 nativeCreate = getNative(Object, 'create'), |
| 761 nativeFloor = Math.floor, |
| 762 nativeIsArray = getNative(Array, 'isArray'), |
| 763 nativeIsFinite = context.isFinite, |
| 764 nativeKeys = getNative(Object, 'keys'), |
| 765 nativeMax = Math.max, |
| 766 nativeMin = Math.min, |
| 767 nativeNow = getNative(Date, 'now'), |
| 768 nativeParseInt = context.parseInt, |
| 769 nativeRandom = Math.random; |
| 770 |
| 771 /** Used as references for `-Infinity` and `Infinity`. */ |
| 772 var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, |
| 773 POSITIVE_INFINITY = Number.POSITIVE_INFINITY; |
| 774 |
| 775 /** Used as references for the maximum length and index of an array. */ |
| 776 var MAX_ARRAY_LENGTH = 4294967295, |
| 777 MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, |
| 778 HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; |
| 779 |
| 780 /** |
| 781 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#
sec-number.max_safe_integer) |
| 782 * of an array-like value. |
| 783 */ |
| 784 var MAX_SAFE_INTEGER = 9007199254740991; |
| 785 |
| 786 /** Used to store function metadata. */ |
| 787 var metaMap = WeakMap && new WeakMap; |
| 788 |
| 789 /** Used to lookup unminified function names. */ |
| 790 var realNames = {}; |
| 791 |
| 792 /*------------------------------------------------------------------------*/ |
| 793 |
| 794 /** |
| 795 * Creates a `lodash` object which wraps `value` to enable implicit chaining
. |
| 796 * Methods that operate on and return arrays, collections, and functions can |
| 797 * be chained together. Methods that retrieve a single value or may return a |
| 798 * primitive value will automatically end the chain returning the unwrapped |
| 799 * value. Explicit chaining may be enabled using `_.chain`. The execution of |
| 800 * chained methods is lazy, that is, execution is deferred until `_#value` |
| 801 * is implicitly or explicitly called. |
| 802 * |
| 803 * Lazy evaluation allows several methods to support shortcut fusion. Shortc
ut |
| 804 * fusion is an optimization strategy which merge iteratee calls; this can h
elp |
| 805 * to avoid the creation of intermediate data structures and greatly reduce
the |
| 806 * number of iteratee executions. |
| 807 * |
| 808 * Chaining is supported in custom builds as long as the `_#value` method is |
| 809 * directly or indirectly included in the build. |
| 810 * |
| 811 * In addition to lodash methods, wrappers have `Array` and `String` methods
. |
| 812 * |
| 813 * The wrapper `Array` methods are: |
| 814 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, |
| 815 * `splice`, and `unshift` |
| 816 * |
| 817 * The wrapper `String` methods are: |
| 818 * `replace` and `split` |
| 819 * |
| 820 * The wrapper methods that support shortcut fusion are: |
| 821 * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, |
| 822 * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, |
| 823 * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, |
| 824 * and `where` |
| 825 * |
| 826 * The chainable wrapper methods are: |
| 827 * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, |
| 828 * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, |
| 829 * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, |
| 830 * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, |
| 831 * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRig
ht`, |
| 832 * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`
, |
| 833 * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, |
| 834 * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, |
| 835 * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, |
| 836 * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, |
| 837 * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, |
| 838 * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restPara
m`, |
| 839 * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, |
| 840 * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, |
| 841 * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObjec
t`, |
| 842 * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, |
| 843 * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWi
th` |
| 844 * |
| 845 * The wrapper methods that are **not** chainable by default are: |
| 846 * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`
, |
| 847 * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findInd
ex`, |
| 848 * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `firs
t`, |
| 849 * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, |
| 850 * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, |
| 851 * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, |
| 852 * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, |
| 853 * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase
`, |
| 854 * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, |
| 855 * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce
`, |
| 856 * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `siz
e`, |
| 857 * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, |
| 858 * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`
, |
| 859 * `unescape`, `uniqueId`, `value`, and `words` |
| 860 * |
| 861 * The wrapper method `sample` will return a wrapped value when `n` is provi
ded, |
| 862 * otherwise an unwrapped value is returned. |
| 863 * |
| 864 * @name _ |
| 865 * @constructor |
| 866 * @category Chain |
| 867 * @param {*} value The value to wrap in a `lodash` instance. |
| 868 * @returns {Object} Returns the new `lodash` wrapper instance. |
| 869 * @example |
| 870 * |
| 871 * var wrapped = _([1, 2, 3]); |
| 872 * |
| 873 * // returns an unwrapped value |
| 874 * wrapped.reduce(function(total, n) { |
| 875 * return total + n; |
| 876 * }); |
| 877 * // => 6 |
| 878 * |
| 879 * // returns a wrapped value |
| 880 * var squares = wrapped.map(function(n) { |
| 881 * return n * n; |
| 882 * }); |
| 883 * |
| 884 * _.isArray(squares); |
| 885 * // => false |
| 886 * |
| 887 * _.isArray(squares.value()); |
| 888 * // => true |
| 889 */ |
| 890 function lodash(value) { |
| 891 if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapp
er)) { |
| 892 if (value instanceof LodashWrapper) { |
| 893 return value; |
| 894 } |
| 895 if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value
, '__wrapped__')) { |
| 896 return wrapperClone(value); |
| 897 } |
| 898 } |
| 899 return new LodashWrapper(value); |
| 900 } |
| 901 |
| 902 /** |
| 903 * The function whose prototype all chaining wrappers inherit from. |
| 904 * |
| 905 * @private |
| 906 */ |
| 907 function baseLodash() { |
| 908 // No operation performed. |
| 909 } |
| 910 |
| 911 /** |
| 912 * The base constructor for creating `lodash` wrapper objects. |
| 913 * |
| 914 * @private |
| 915 * @param {*} value The value to wrap. |
| 916 * @param {boolean} [chainAll] Enable chaining for all wrapper methods. |
| 917 * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped va
lue. |
| 918 */ |
| 919 function LodashWrapper(value, chainAll, actions) { |
| 920 this.__wrapped__ = value; |
| 921 this.__actions__ = actions || []; |
| 922 this.__chain__ = !!chainAll; |
| 923 } |
| 924 |
| 925 /** |
| 926 * An object environment feature flags. |
| 927 * |
| 928 * @static |
| 929 * @memberOf _ |
| 930 * @type Object |
| 931 */ |
| 932 var support = lodash.support = {}; |
| 933 |
| 934 /** |
| 935 * By default, the template delimiters used by lodash are like those in |
| 936 * embedded Ruby (ERB). Change the following template settings to use |
| 937 * alternative delimiters. |
| 938 * |
| 939 * @static |
| 940 * @memberOf _ |
| 941 * @type Object |
| 942 */ |
| 943 lodash.templateSettings = { |
| 944 |
| 945 /** |
| 946 * Used to detect `data` property values to be HTML-escaped. |
| 947 * |
| 948 * @memberOf _.templateSettings |
| 949 * @type RegExp |
| 950 */ |
| 951 'escape': reEscape, |
| 952 |
| 953 /** |
| 954 * Used to detect code to be evaluated. |
| 955 * |
| 956 * @memberOf _.templateSettings |
| 957 * @type RegExp |
| 958 */ |
| 959 'evaluate': reEvaluate, |
| 960 |
| 961 /** |
| 962 * Used to detect `data` property values to inject. |
| 963 * |
| 964 * @memberOf _.templateSettings |
| 965 * @type RegExp |
| 966 */ |
| 967 'interpolate': reInterpolate, |
| 968 |
| 969 /** |
| 970 * Used to reference the data object in the template text. |
| 971 * |
| 972 * @memberOf _.templateSettings |
| 973 * @type string |
| 974 */ |
| 975 'variable': '', |
| 976 |
| 977 /** |
| 978 * Used to import variables into the compiled template. |
| 979 * |
| 980 * @memberOf _.templateSettings |
| 981 * @type Object |
| 982 */ |
| 983 'imports': { |
| 984 |
| 985 /** |
| 986 * A reference to the `lodash` function. |
| 987 * |
| 988 * @memberOf _.templateSettings.imports |
| 989 * @type Function |
| 990 */ |
| 991 '_': lodash |
| 992 } |
| 993 }; |
| 994 |
| 995 /*------------------------------------------------------------------------*/ |
| 996 |
| 997 /** |
| 998 * Creates a lazy wrapper object which wraps `value` to enable lazy evaluati
on. |
| 999 * |
| 1000 * @private |
| 1001 * @param {*} value The value to wrap. |
| 1002 */ |
| 1003 function LazyWrapper(value) { |
| 1004 this.__wrapped__ = value; |
| 1005 this.__actions__ = []; |
| 1006 this.__dir__ = 1; |
| 1007 this.__filtered__ = false; |
| 1008 this.__iteratees__ = []; |
| 1009 this.__takeCount__ = POSITIVE_INFINITY; |
| 1010 this.__views__ = []; |
| 1011 } |
| 1012 |
| 1013 /** |
| 1014 * Creates a clone of the lazy wrapper object. |
| 1015 * |
| 1016 * @private |
| 1017 * @name clone |
| 1018 * @memberOf LazyWrapper |
| 1019 * @returns {Object} Returns the cloned `LazyWrapper` object. |
| 1020 */ |
| 1021 function lazyClone() { |
| 1022 var result = new LazyWrapper(this.__wrapped__); |
| 1023 result.__actions__ = arrayCopy(this.__actions__); |
| 1024 result.__dir__ = this.__dir__; |
| 1025 result.__filtered__ = this.__filtered__; |
| 1026 result.__iteratees__ = arrayCopy(this.__iteratees__); |
| 1027 result.__takeCount__ = this.__takeCount__; |
| 1028 result.__views__ = arrayCopy(this.__views__); |
| 1029 return result; |
| 1030 } |
| 1031 |
| 1032 /** |
| 1033 * Reverses the direction of lazy iteration. |
| 1034 * |
| 1035 * @private |
| 1036 * @name reverse |
| 1037 * @memberOf LazyWrapper |
| 1038 * @returns {Object} Returns the new reversed `LazyWrapper` object. |
| 1039 */ |
| 1040 function lazyReverse() { |
| 1041 if (this.__filtered__) { |
| 1042 var result = new LazyWrapper(this); |
| 1043 result.__dir__ = -1; |
| 1044 result.__filtered__ = true; |
| 1045 } else { |
| 1046 result = this.clone(); |
| 1047 result.__dir__ *= -1; |
| 1048 } |
| 1049 return result; |
| 1050 } |
| 1051 |
| 1052 /** |
| 1053 * Extracts the unwrapped value from its lazy wrapper. |
| 1054 * |
| 1055 * @private |
| 1056 * @name value |
| 1057 * @memberOf LazyWrapper |
| 1058 * @returns {*} Returns the unwrapped value. |
| 1059 */ |
| 1060 function lazyValue() { |
| 1061 var array = this.__wrapped__.value(), |
| 1062 dir = this.__dir__, |
| 1063 isArr = isArray(array), |
| 1064 isRight = dir < 0, |
| 1065 arrLength = isArr ? array.length : 0, |
| 1066 view = getView(0, arrLength, this.__views__), |
| 1067 start = view.start, |
| 1068 end = view.end, |
| 1069 length = end - start, |
| 1070 index = isRight ? end : (start - 1), |
| 1071 iteratees = this.__iteratees__, |
| 1072 iterLength = iteratees.length, |
| 1073 resIndex = 0, |
| 1074 takeCount = nativeMin(length, this.__takeCount__); |
| 1075 |
| 1076 if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && take
Count == length)) { |
| 1077 return baseWrapperValue(array, this.__actions__); |
| 1078 } |
| 1079 var result = []; |
| 1080 |
| 1081 outer: |
| 1082 while (length-- && resIndex < takeCount) { |
| 1083 index += dir; |
| 1084 |
| 1085 var iterIndex = -1, |
| 1086 value = array[index]; |
| 1087 |
| 1088 while (++iterIndex < iterLength) { |
| 1089 var data = iteratees[iterIndex], |
| 1090 iteratee = data.iteratee, |
| 1091 type = data.type, |
| 1092 computed = iteratee(value); |
| 1093 |
| 1094 if (type == LAZY_MAP_FLAG) { |
| 1095 value = computed; |
| 1096 } else if (!computed) { |
| 1097 if (type == LAZY_FILTER_FLAG) { |
| 1098 continue outer; |
| 1099 } else { |
| 1100 break outer; |
| 1101 } |
| 1102 } |
| 1103 } |
| 1104 result[resIndex++] = value; |
| 1105 } |
| 1106 return result; |
| 1107 } |
| 1108 |
| 1109 /*------------------------------------------------------------------------*/ |
| 1110 |
| 1111 /** |
| 1112 * Creates a cache object to store key/value pairs. |
| 1113 * |
| 1114 * @private |
| 1115 * @static |
| 1116 * @name Cache |
| 1117 * @memberOf _.memoize |
| 1118 */ |
| 1119 function MapCache() { |
| 1120 this.__data__ = {}; |
| 1121 } |
| 1122 |
| 1123 /** |
| 1124 * Removes `key` and its value from the cache. |
| 1125 * |
| 1126 * @private |
| 1127 * @name delete |
| 1128 * @memberOf _.memoize.Cache |
| 1129 * @param {string} key The key of the value to remove. |
| 1130 * @returns {boolean} Returns `true` if the entry was removed successfully,
else `false`. |
| 1131 */ |
| 1132 function mapDelete(key) { |
| 1133 return this.has(key) && delete this.__data__[key]; |
| 1134 } |
| 1135 |
| 1136 /** |
| 1137 * Gets the cached value for `key`. |
| 1138 * |
| 1139 * @private |
| 1140 * @name get |
| 1141 * @memberOf _.memoize.Cache |
| 1142 * @param {string} key The key of the value to get. |
| 1143 * @returns {*} Returns the cached value. |
| 1144 */ |
| 1145 function mapGet(key) { |
| 1146 return key == '__proto__' ? undefined : this.__data__[key]; |
| 1147 } |
| 1148 |
| 1149 /** |
| 1150 * Checks if a cached value for `key` exists. |
| 1151 * |
| 1152 * @private |
| 1153 * @name has |
| 1154 * @memberOf _.memoize.Cache |
| 1155 * @param {string} key The key of the entry to check. |
| 1156 * @returns {boolean} Returns `true` if an entry for `key` exists, else `fal
se`. |
| 1157 */ |
| 1158 function mapHas(key) { |
| 1159 return key != '__proto__' && hasOwnProperty.call(this.__data__, key); |
| 1160 } |
| 1161 |
| 1162 /** |
| 1163 * Sets `value` to `key` of the cache. |
| 1164 * |
| 1165 * @private |
| 1166 * @name set |
| 1167 * @memberOf _.memoize.Cache |
| 1168 * @param {string} key The key of the value to cache. |
| 1169 * @param {*} value The value to cache. |
| 1170 * @returns {Object} Returns the cache object. |
| 1171 */ |
| 1172 function mapSet(key, value) { |
| 1173 if (key != '__proto__') { |
| 1174 this.__data__[key] = value; |
| 1175 } |
| 1176 return this; |
| 1177 } |
| 1178 |
| 1179 /*------------------------------------------------------------------------*/ |
| 1180 |
| 1181 /** |
| 1182 * |
| 1183 * Creates a cache object to store unique values. |
| 1184 * |
| 1185 * @private |
| 1186 * @param {Array} [values] The values to cache. |
| 1187 */ |
| 1188 function SetCache(values) { |
| 1189 var length = values ? values.length : 0; |
| 1190 |
| 1191 this.data = { 'hash': nativeCreate(null), 'set': new Set }; |
| 1192 while (length--) { |
| 1193 this.push(values[length]); |
| 1194 } |
| 1195 } |
| 1196 |
| 1197 /** |
| 1198 * Checks if `value` is in `cache` mimicking the return signature of |
| 1199 * `_.indexOf` by returning `0` if the value is found, else `-1`. |
| 1200 * |
| 1201 * @private |
| 1202 * @param {Object} cache The cache to search. |
| 1203 * @param {*} value The value to search for. |
| 1204 * @returns {number} Returns `0` if `value` is found, else `-1`. |
| 1205 */ |
| 1206 function cacheIndexOf(cache, value) { |
| 1207 var data = cache.data, |
| 1208 result = (typeof value == 'string' || isObject(value)) ? data.set.has(
value) : data.hash[value]; |
| 1209 |
| 1210 return result ? 0 : -1; |
| 1211 } |
| 1212 |
| 1213 /** |
| 1214 * Adds `value` to the cache. |
| 1215 * |
| 1216 * @private |
| 1217 * @name push |
| 1218 * @memberOf SetCache |
| 1219 * @param {*} value The value to cache. |
| 1220 */ |
| 1221 function cachePush(value) { |
| 1222 var data = this.data; |
| 1223 if (typeof value == 'string' || isObject(value)) { |
| 1224 data.set.add(value); |
| 1225 } else { |
| 1226 data.hash[value] = true; |
| 1227 } |
| 1228 } |
| 1229 |
| 1230 /*------------------------------------------------------------------------*/ |
| 1231 |
| 1232 /** |
| 1233 * Creates a new array joining `array` with `other`. |
| 1234 * |
| 1235 * @private |
| 1236 * @param {Array} array The array to join. |
| 1237 * @param {Array} other The other array to join. |
| 1238 * @returns {Array} Returns the new concatenated array. |
| 1239 */ |
| 1240 function arrayConcat(array, other) { |
| 1241 var index = -1, |
| 1242 length = array.length, |
| 1243 othIndex = -1, |
| 1244 othLength = other.length, |
| 1245 result = Array(length + othLength); |
| 1246 |
| 1247 while (++index < length) { |
| 1248 result[index] = array[index]; |
| 1249 } |
| 1250 while (++othIndex < othLength) { |
| 1251 result[index++] = other[othIndex]; |
| 1252 } |
| 1253 return result; |
| 1254 } |
| 1255 |
| 1256 /** |
| 1257 * Copies the values of `source` to `array`. |
| 1258 * |
| 1259 * @private |
| 1260 * @param {Array} source The array to copy values from. |
| 1261 * @param {Array} [array=[]] The array to copy values to. |
| 1262 * @returns {Array} Returns `array`. |
| 1263 */ |
| 1264 function arrayCopy(source, array) { |
| 1265 var index = -1, |
| 1266 length = source.length; |
| 1267 |
| 1268 array || (array = Array(length)); |
| 1269 while (++index < length) { |
| 1270 array[index] = source[index]; |
| 1271 } |
| 1272 return array; |
| 1273 } |
| 1274 |
| 1275 /** |
| 1276 * A specialized version of `_.forEach` for arrays without support for callb
ack |
| 1277 * shorthands and `this` binding. |
| 1278 * |
| 1279 * @private |
| 1280 * @param {Array} array The array to iterate over. |
| 1281 * @param {Function} iteratee The function invoked per iteration. |
| 1282 * @returns {Array} Returns `array`. |
| 1283 */ |
| 1284 function arrayEach(array, iteratee) { |
| 1285 var index = -1, |
| 1286 length = array.length; |
| 1287 |
| 1288 while (++index < length) { |
| 1289 if (iteratee(array[index], index, array) === false) { |
| 1290 break; |
| 1291 } |
| 1292 } |
| 1293 return array; |
| 1294 } |
| 1295 |
| 1296 /** |
| 1297 * A specialized version of `_.forEachRight` for arrays without support for |
| 1298 * callback shorthands and `this` binding. |
| 1299 * |
| 1300 * @private |
| 1301 * @param {Array} array The array to iterate over. |
| 1302 * @param {Function} iteratee The function invoked per iteration. |
| 1303 * @returns {Array} Returns `array`. |
| 1304 */ |
| 1305 function arrayEachRight(array, iteratee) { |
| 1306 var length = array.length; |
| 1307 |
| 1308 while (length--) { |
| 1309 if (iteratee(array[length], length, array) === false) { |
| 1310 break; |
| 1311 } |
| 1312 } |
| 1313 return array; |
| 1314 } |
| 1315 |
| 1316 /** |
| 1317 * A specialized version of `_.every` for arrays without support for callbac
k |
| 1318 * shorthands and `this` binding. |
| 1319 * |
| 1320 * @private |
| 1321 * @param {Array} array The array to iterate over. |
| 1322 * @param {Function} predicate The function invoked per iteration. |
| 1323 * @returns {boolean} Returns `true` if all elements pass the predicate chec
k, |
| 1324 * else `false`. |
| 1325 */ |
| 1326 function arrayEvery(array, predicate) { |
| 1327 var index = -1, |
| 1328 length = array.length; |
| 1329 |
| 1330 while (++index < length) { |
| 1331 if (!predicate(array[index], index, array)) { |
| 1332 return false; |
| 1333 } |
| 1334 } |
| 1335 return true; |
| 1336 } |
| 1337 |
| 1338 /** |
| 1339 * A specialized version of `baseExtremum` for arrays which invokes `iterate
e` |
| 1340 * with one argument: (value). |
| 1341 * |
| 1342 * @private |
| 1343 * @param {Array} array The array to iterate over. |
| 1344 * @param {Function} iteratee The function invoked per iteration. |
| 1345 * @param {Function} comparator The function used to compare values. |
| 1346 * @param {*} exValue The initial extremum value. |
| 1347 * @returns {*} Returns the extremum value. |
| 1348 */ |
| 1349 function arrayExtremum(array, iteratee, comparator, exValue) { |
| 1350 var index = -1, |
| 1351 length = array.length, |
| 1352 computed = exValue, |
| 1353 result = computed; |
| 1354 |
| 1355 while (++index < length) { |
| 1356 var value = array[index], |
| 1357 current = +iteratee(value); |
| 1358 |
| 1359 if (comparator(current, computed)) { |
| 1360 computed = current; |
| 1361 result = value; |
| 1362 } |
| 1363 } |
| 1364 return result; |
| 1365 } |
| 1366 |
| 1367 /** |
| 1368 * A specialized version of `_.filter` for arrays without support for callba
ck |
| 1369 * shorthands and `this` binding. |
| 1370 * |
| 1371 * @private |
| 1372 * @param {Array} array The array to iterate over. |
| 1373 * @param {Function} predicate The function invoked per iteration. |
| 1374 * @returns {Array} Returns the new filtered array. |
| 1375 */ |
| 1376 function arrayFilter(array, predicate) { |
| 1377 var index = -1, |
| 1378 length = array.length, |
| 1379 resIndex = -1, |
| 1380 result = []; |
| 1381 |
| 1382 while (++index < length) { |
| 1383 var value = array[index]; |
| 1384 if (predicate(value, index, array)) { |
| 1385 result[++resIndex] = value; |
| 1386 } |
| 1387 } |
| 1388 return result; |
| 1389 } |
| 1390 |
| 1391 /** |
| 1392 * A specialized version of `_.map` for arrays without support for callback |
| 1393 * shorthands and `this` binding. |
| 1394 * |
| 1395 * @private |
| 1396 * @param {Array} array The array to iterate over. |
| 1397 * @param {Function} iteratee The function invoked per iteration. |
| 1398 * @returns {Array} Returns the new mapped array. |
| 1399 */ |
| 1400 function arrayMap(array, iteratee) { |
| 1401 var index = -1, |
| 1402 length = array.length, |
| 1403 result = Array(length); |
| 1404 |
| 1405 while (++index < length) { |
| 1406 result[index] = iteratee(array[index], index, array); |
| 1407 } |
| 1408 return result; |
| 1409 } |
| 1410 |
| 1411 /** |
| 1412 * Appends the elements of `values` to `array`. |
| 1413 * |
| 1414 * @private |
| 1415 * @param {Array} array The array to modify. |
| 1416 * @param {Array} values The values to append. |
| 1417 * @returns {Array} Returns `array`. |
| 1418 */ |
| 1419 function arrayPush(array, values) { |
| 1420 var index = -1, |
| 1421 length = values.length, |
| 1422 offset = array.length; |
| 1423 |
| 1424 while (++index < length) { |
| 1425 array[offset + index] = values[index]; |
| 1426 } |
| 1427 return array; |
| 1428 } |
| 1429 |
| 1430 /** |
| 1431 * A specialized version of `_.reduce` for arrays without support for callba
ck |
| 1432 * shorthands and `this` binding. |
| 1433 * |
| 1434 * @private |
| 1435 * @param {Array} array The array to iterate over. |
| 1436 * @param {Function} iteratee The function invoked per iteration. |
| 1437 * @param {*} [accumulator] The initial value. |
| 1438 * @param {boolean} [initFromArray] Specify using the first element of `arra
y` |
| 1439 * as the initial value. |
| 1440 * @returns {*} Returns the accumulated value. |
| 1441 */ |
| 1442 function arrayReduce(array, iteratee, accumulator, initFromArray) { |
| 1443 var index = -1, |
| 1444 length = array.length; |
| 1445 |
| 1446 if (initFromArray && length) { |
| 1447 accumulator = array[++index]; |
| 1448 } |
| 1449 while (++index < length) { |
| 1450 accumulator = iteratee(accumulator, array[index], index, array); |
| 1451 } |
| 1452 return accumulator; |
| 1453 } |
| 1454 |
| 1455 /** |
| 1456 * A specialized version of `_.reduceRight` for arrays without support for |
| 1457 * callback shorthands and `this` binding. |
| 1458 * |
| 1459 * @private |
| 1460 * @param {Array} array The array to iterate over. |
| 1461 * @param {Function} iteratee The function invoked per iteration. |
| 1462 * @param {*} [accumulator] The initial value. |
| 1463 * @param {boolean} [initFromArray] Specify using the last element of `array
` |
| 1464 * as the initial value. |
| 1465 * @returns {*} Returns the accumulated value. |
| 1466 */ |
| 1467 function arrayReduceRight(array, iteratee, accumulator, initFromArray) { |
| 1468 var length = array.length; |
| 1469 if (initFromArray && length) { |
| 1470 accumulator = array[--length]; |
| 1471 } |
| 1472 while (length--) { |
| 1473 accumulator = iteratee(accumulator, array[length], length, array); |
| 1474 } |
| 1475 return accumulator; |
| 1476 } |
| 1477 |
| 1478 /** |
| 1479 * A specialized version of `_.some` for arrays without support for callback |
| 1480 * shorthands and `this` binding. |
| 1481 * |
| 1482 * @private |
| 1483 * @param {Array} array The array to iterate over. |
| 1484 * @param {Function} predicate The function invoked per iteration. |
| 1485 * @returns {boolean} Returns `true` if any element passes the predicate che
ck, |
| 1486 * else `false`. |
| 1487 */ |
| 1488 function arraySome(array, predicate) { |
| 1489 var index = -1, |
| 1490 length = array.length; |
| 1491 |
| 1492 while (++index < length) { |
| 1493 if (predicate(array[index], index, array)) { |
| 1494 return true; |
| 1495 } |
| 1496 } |
| 1497 return false; |
| 1498 } |
| 1499 |
| 1500 /** |
| 1501 * A specialized version of `_.sum` for arrays without support for callback |
| 1502 * shorthands and `this` binding.. |
| 1503 * |
| 1504 * @private |
| 1505 * @param {Array} array The array to iterate over. |
| 1506 * @param {Function} iteratee The function invoked per iteration. |
| 1507 * @returns {number} Returns the sum. |
| 1508 */ |
| 1509 function arraySum(array, iteratee) { |
| 1510 var length = array.length, |
| 1511 result = 0; |
| 1512 |
| 1513 while (length--) { |
| 1514 result += +iteratee(array[length]) || 0; |
| 1515 } |
| 1516 return result; |
| 1517 } |
| 1518 |
| 1519 /** |
| 1520 * Used by `_.defaults` to customize its `_.assign` use. |
| 1521 * |
| 1522 * @private |
| 1523 * @param {*} objectValue The destination object property value. |
| 1524 * @param {*} sourceValue The source object property value. |
| 1525 * @returns {*} Returns the value to assign to the destination object. |
| 1526 */ |
| 1527 function assignDefaults(objectValue, sourceValue) { |
| 1528 return objectValue === undefined ? sourceValue : objectValue; |
| 1529 } |
| 1530 |
| 1531 /** |
| 1532 * Used by `_.template` to customize its `_.assign` use. |
| 1533 * |
| 1534 * **Note:** This function is like `assignDefaults` except that it ignores |
| 1535 * inherited property values when checking if a property is `undefined`. |
| 1536 * |
| 1537 * @private |
| 1538 * @param {*} objectValue The destination object property value. |
| 1539 * @param {*} sourceValue The source object property value. |
| 1540 * @param {string} key The key associated with the object and source values. |
| 1541 * @param {Object} object The destination object. |
| 1542 * @returns {*} Returns the value to assign to the destination object. |
| 1543 */ |
| 1544 function assignOwnDefaults(objectValue, sourceValue, key, object) { |
| 1545 return (objectValue === undefined || !hasOwnProperty.call(object, key)) |
| 1546 ? sourceValue |
| 1547 : objectValue; |
| 1548 } |
| 1549 |
| 1550 /** |
| 1551 * A specialized version of `_.assign` for customizing assigned values witho
ut |
| 1552 * support for argument juggling, multiple sources, and `this` binding `cust
omizer` |
| 1553 * functions. |
| 1554 * |
| 1555 * @private |
| 1556 * @param {Object} object The destination object. |
| 1557 * @param {Object} source The source object. |
| 1558 * @param {Function} customizer The function to customize assigned values. |
| 1559 * @returns {Object} Returns `object`. |
| 1560 */ |
| 1561 function assignWith(object, source, customizer) { |
| 1562 var index = -1, |
| 1563 props = keys(source), |
| 1564 length = props.length; |
| 1565 |
| 1566 while (++index < length) { |
| 1567 var key = props[index], |
| 1568 value = object[key], |
| 1569 result = customizer(value, source[key], key, object, source); |
| 1570 |
| 1571 if ((result === result ? (result !== value) : (value === value)) || |
| 1572 (value === undefined && !(key in object))) { |
| 1573 object[key] = result; |
| 1574 } |
| 1575 } |
| 1576 return object; |
| 1577 } |
| 1578 |
| 1579 /** |
| 1580 * The base implementation of `_.assign` without support for argument juggli
ng, |
| 1581 * multiple sources, and `customizer` functions. |
| 1582 * |
| 1583 * @private |
| 1584 * @param {Object} object The destination object. |
| 1585 * @param {Object} source The source object. |
| 1586 * @returns {Object} Returns `object`. |
| 1587 */ |
| 1588 function baseAssign(object, source) { |
| 1589 return source == null |
| 1590 ? object |
| 1591 : baseCopy(source, keys(source), object); |
| 1592 } |
| 1593 |
| 1594 /** |
| 1595 * The base implementation of `_.at` without support for string collections |
| 1596 * and individual key arguments. |
| 1597 * |
| 1598 * @private |
| 1599 * @param {Array|Object} collection The collection to iterate over. |
| 1600 * @param {number[]|string[]} props The property names or indexes of element
s to pick. |
| 1601 * @returns {Array} Returns the new array of picked elements. |
| 1602 */ |
| 1603 function baseAt(collection, props) { |
| 1604 var index = -1, |
| 1605 isNil = collection == null, |
| 1606 isArr = !isNil && isArrayLike(collection), |
| 1607 length = isArr ? collection.length : 0, |
| 1608 propsLength = props.length, |
| 1609 result = Array(propsLength); |
| 1610 |
| 1611 while(++index < propsLength) { |
| 1612 var key = props[index]; |
| 1613 if (isArr) { |
| 1614 result[index] = isIndex(key, length) ? collection[key] : undefined; |
| 1615 } else { |
| 1616 result[index] = isNil ? undefined : collection[key]; |
| 1617 } |
| 1618 } |
| 1619 return result; |
| 1620 } |
| 1621 |
| 1622 /** |
| 1623 * Copies properties of `source` to `object`. |
| 1624 * |
| 1625 * @private |
| 1626 * @param {Object} source The object to copy properties from. |
| 1627 * @param {Array} props The property names to copy. |
| 1628 * @param {Object} [object={}] The object to copy properties to. |
| 1629 * @returns {Object} Returns `object`. |
| 1630 */ |
| 1631 function baseCopy(source, props, object) { |
| 1632 object || (object = {}); |
| 1633 |
| 1634 var index = -1, |
| 1635 length = props.length; |
| 1636 |
| 1637 while (++index < length) { |
| 1638 var key = props[index]; |
| 1639 object[key] = source[key]; |
| 1640 } |
| 1641 return object; |
| 1642 } |
| 1643 |
| 1644 /** |
| 1645 * The base implementation of `_.callback` which supports specifying the |
| 1646 * number of arguments to provide to `func`. |
| 1647 * |
| 1648 * @private |
| 1649 * @param {*} [func=_.identity] The value to convert to a callback. |
| 1650 * @param {*} [thisArg] The `this` binding of `func`. |
| 1651 * @param {number} [argCount] The number of arguments to provide to `func`. |
| 1652 * @returns {Function} Returns the callback. |
| 1653 */ |
| 1654 function baseCallback(func, thisArg, argCount) { |
| 1655 var type = typeof func; |
| 1656 if (type == 'function') { |
| 1657 return thisArg === undefined |
| 1658 ? func |
| 1659 : bindCallback(func, thisArg, argCount); |
| 1660 } |
| 1661 if (func == null) { |
| 1662 return identity; |
| 1663 } |
| 1664 if (type == 'object') { |
| 1665 return baseMatches(func); |
| 1666 } |
| 1667 return thisArg === undefined |
| 1668 ? property(func) |
| 1669 : baseMatchesProperty(func, thisArg); |
| 1670 } |
| 1671 |
| 1672 /** |
| 1673 * The base implementation of `_.clone` without support for argument jugglin
g |
| 1674 * and `this` binding `customizer` functions. |
| 1675 * |
| 1676 * @private |
| 1677 * @param {*} value The value to clone. |
| 1678 * @param {boolean} [isDeep] Specify a deep clone. |
| 1679 * @param {Function} [customizer] The function to customize cloning values. |
| 1680 * @param {string} [key] The key of `value`. |
| 1681 * @param {Object} [object] The object `value` belongs to. |
| 1682 * @param {Array} [stackA=[]] Tracks traversed source objects. |
| 1683 * @param {Array} [stackB=[]] Associates clones with source counterparts. |
| 1684 * @returns {*} Returns the cloned value. |
| 1685 */ |
| 1686 function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { |
| 1687 var result; |
| 1688 if (customizer) { |
| 1689 result = object ? customizer(value, key, object) : customizer(value); |
| 1690 } |
| 1691 if (result !== undefined) { |
| 1692 return result; |
| 1693 } |
| 1694 if (!isObject(value)) { |
| 1695 return value; |
| 1696 } |
| 1697 var isArr = isArray(value); |
| 1698 if (isArr) { |
| 1699 result = initCloneArray(value); |
| 1700 if (!isDeep) { |
| 1701 return arrayCopy(value, result); |
| 1702 } |
| 1703 } else { |
| 1704 var tag = objToString.call(value), |
| 1705 isFunc = tag == funcTag; |
| 1706 |
| 1707 if (tag == objectTag || tag == argsTag || (isFunc && !object)) { |
| 1708 result = initCloneObject(isFunc ? {} : value); |
| 1709 if (!isDeep) { |
| 1710 return baseAssign(result, value); |
| 1711 } |
| 1712 } else { |
| 1713 return cloneableTags[tag] |
| 1714 ? initCloneByTag(value, tag, isDeep) |
| 1715 : (object ? value : {}); |
| 1716 } |
| 1717 } |
| 1718 // Check for circular references and return its corresponding clone. |
| 1719 stackA || (stackA = []); |
| 1720 stackB || (stackB = []); |
| 1721 |
| 1722 var length = stackA.length; |
| 1723 while (length--) { |
| 1724 if (stackA[length] == value) { |
| 1725 return stackB[length]; |
| 1726 } |
| 1727 } |
| 1728 // Add the source value to the stack of traversed objects and associate it
with its clone. |
| 1729 stackA.push(value); |
| 1730 stackB.push(result); |
| 1731 |
| 1732 // Recursively populate clone (susceptible to call stack limits). |
| 1733 (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { |
| 1734 result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA
, stackB); |
| 1735 }); |
| 1736 return result; |
| 1737 } |
| 1738 |
| 1739 /** |
| 1740 * The base implementation of `_.create` without support for assigning |
| 1741 * properties to the created object. |
| 1742 * |
| 1743 * @private |
| 1744 * @param {Object} prototype The object to inherit from. |
| 1745 * @returns {Object} Returns the new object. |
| 1746 */ |
| 1747 var baseCreate = (function() { |
| 1748 function object() {} |
| 1749 return function(prototype) { |
| 1750 if (isObject(prototype)) { |
| 1751 object.prototype = prototype; |
| 1752 var result = new object; |
| 1753 object.prototype = undefined; |
| 1754 } |
| 1755 return result || {}; |
| 1756 }; |
| 1757 }()); |
| 1758 |
| 1759 /** |
| 1760 * The base implementation of `_.delay` and `_.defer` which accepts an index |
| 1761 * of where to slice the arguments to provide to `func`. |
| 1762 * |
| 1763 * @private |
| 1764 * @param {Function} func The function to delay. |
| 1765 * @param {number} wait The number of milliseconds to delay invocation. |
| 1766 * @param {Object} args The arguments provide to `func`. |
| 1767 * @returns {number} Returns the timer id. |
| 1768 */ |
| 1769 function baseDelay(func, wait, args) { |
| 1770 if (typeof func != 'function') { |
| 1771 throw new TypeError(FUNC_ERROR_TEXT); |
| 1772 } |
| 1773 return setTimeout(function() { func.apply(undefined, args); }, wait); |
| 1774 } |
| 1775 |
| 1776 /** |
| 1777 * The base implementation of `_.difference` which accepts a single array |
| 1778 * of values to exclude. |
| 1779 * |
| 1780 * @private |
| 1781 * @param {Array} array The array to inspect. |
| 1782 * @param {Array} values The values to exclude. |
| 1783 * @returns {Array} Returns the new array of filtered values. |
| 1784 */ |
| 1785 function baseDifference(array, values) { |
| 1786 var length = array ? array.length : 0, |
| 1787 result = []; |
| 1788 |
| 1789 if (!length) { |
| 1790 return result; |
| 1791 } |
| 1792 var index = -1, |
| 1793 indexOf = getIndexOf(), |
| 1794 isCommon = indexOf === baseIndexOf, |
| 1795 cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(
values) : null, |
| 1796 valuesLength = values.length; |
| 1797 |
| 1798 if (cache) { |
| 1799 indexOf = cacheIndexOf; |
| 1800 isCommon = false; |
| 1801 values = cache; |
| 1802 } |
| 1803 outer: |
| 1804 while (++index < length) { |
| 1805 var value = array[index]; |
| 1806 |
| 1807 if (isCommon && value === value) { |
| 1808 var valuesIndex = valuesLength; |
| 1809 while (valuesIndex--) { |
| 1810 if (values[valuesIndex] === value) { |
| 1811 continue outer; |
| 1812 } |
| 1813 } |
| 1814 result.push(value); |
| 1815 } |
| 1816 else if (indexOf(values, value, 0) < 0) { |
| 1817 result.push(value); |
| 1818 } |
| 1819 } |
| 1820 return result; |
| 1821 } |
| 1822 |
| 1823 /** |
| 1824 * The base implementation of `_.forEach` without support for callback |
| 1825 * shorthands and `this` binding. |
| 1826 * |
| 1827 * @private |
| 1828 * @param {Array|Object|string} collection The collection to iterate over. |
| 1829 * @param {Function} iteratee The function invoked per iteration. |
| 1830 * @returns {Array|Object|string} Returns `collection`. |
| 1831 */ |
| 1832 var baseEach = createBaseEach(baseForOwn); |
| 1833 |
| 1834 /** |
| 1835 * The base implementation of `_.forEachRight` without support for callback |
| 1836 * shorthands and `this` binding. |
| 1837 * |
| 1838 * @private |
| 1839 * @param {Array|Object|string} collection The collection to iterate over. |
| 1840 * @param {Function} iteratee The function invoked per iteration. |
| 1841 * @returns {Array|Object|string} Returns `collection`. |
| 1842 */ |
| 1843 var baseEachRight = createBaseEach(baseForOwnRight, true); |
| 1844 |
| 1845 /** |
| 1846 * The base implementation of `_.every` without support for callback |
| 1847 * shorthands and `this` binding. |
| 1848 * |
| 1849 * @private |
| 1850 * @param {Array|Object|string} collection The collection to iterate over. |
| 1851 * @param {Function} predicate The function invoked per iteration. |
| 1852 * @returns {boolean} Returns `true` if all elements pass the predicate chec
k, |
| 1853 * else `false` |
| 1854 */ |
| 1855 function baseEvery(collection, predicate) { |
| 1856 var result = true; |
| 1857 baseEach(collection, function(value, index, collection) { |
| 1858 result = !!predicate(value, index, collection); |
| 1859 return result; |
| 1860 }); |
| 1861 return result; |
| 1862 } |
| 1863 |
| 1864 /** |
| 1865 * Gets the extremum value of `collection` invoking `iteratee` for each valu
e |
| 1866 * in `collection` to generate the criterion by which the value is ranked. |
| 1867 * The `iteratee` is invoked with three arguments: (value, index|key, collec
tion). |
| 1868 * |
| 1869 * @private |
| 1870 * @param {Array|Object|string} collection The collection to iterate over. |
| 1871 * @param {Function} iteratee The function invoked per iteration. |
| 1872 * @param {Function} comparator The function used to compare values. |
| 1873 * @param {*} exValue The initial extremum value. |
| 1874 * @returns {*} Returns the extremum value. |
| 1875 */ |
| 1876 function baseExtremum(collection, iteratee, comparator, exValue) { |
| 1877 var computed = exValue, |
| 1878 result = computed; |
| 1879 |
| 1880 baseEach(collection, function(value, index, collection) { |
| 1881 var current = +iteratee(value, index, collection); |
| 1882 if (comparator(current, computed) || (current === exValue && current ===
result)) { |
| 1883 computed = current; |
| 1884 result = value; |
| 1885 } |
| 1886 }); |
| 1887 return result; |
| 1888 } |
| 1889 |
| 1890 /** |
| 1891 * The base implementation of `_.fill` without an iteratee call guard. |
| 1892 * |
| 1893 * @private |
| 1894 * @param {Array} array The array to fill. |
| 1895 * @param {*} value The value to fill `array` with. |
| 1896 * @param {number} [start=0] The start position. |
| 1897 * @param {number} [end=array.length] The end position. |
| 1898 * @returns {Array} Returns `array`. |
| 1899 */ |
| 1900 function baseFill(array, value, start, end) { |
| 1901 var length = array.length; |
| 1902 |
| 1903 start = start == null ? 0 : (+start || 0); |
| 1904 if (start < 0) { |
| 1905 start = -start > length ? 0 : (length + start); |
| 1906 } |
| 1907 end = (end === undefined || end > length) ? length : (+end || 0); |
| 1908 if (end < 0) { |
| 1909 end += length; |
| 1910 } |
| 1911 length = start > end ? 0 : (end >>> 0); |
| 1912 start >>>= 0; |
| 1913 |
| 1914 while (start < length) { |
| 1915 array[start++] = value; |
| 1916 } |
| 1917 return array; |
| 1918 } |
| 1919 |
| 1920 /** |
| 1921 * The base implementation of `_.filter` without support for callback |
| 1922 * shorthands and `this` binding. |
| 1923 * |
| 1924 * @private |
| 1925 * @param {Array|Object|string} collection The collection to iterate over. |
| 1926 * @param {Function} predicate The function invoked per iteration. |
| 1927 * @returns {Array} Returns the new filtered array. |
| 1928 */ |
| 1929 function baseFilter(collection, predicate) { |
| 1930 var result = []; |
| 1931 baseEach(collection, function(value, index, collection) { |
| 1932 if (predicate(value, index, collection)) { |
| 1933 result.push(value); |
| 1934 } |
| 1935 }); |
| 1936 return result; |
| 1937 } |
| 1938 |
| 1939 /** |
| 1940 * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.fi
ndLastKey`, |
| 1941 * without support for callback shorthands and `this` binding, which iterate
s |
| 1942 * over `collection` using the provided `eachFunc`. |
| 1943 * |
| 1944 * @private |
| 1945 * @param {Array|Object|string} collection The collection to search. |
| 1946 * @param {Function} predicate The function invoked per iteration. |
| 1947 * @param {Function} eachFunc The function to iterate over `collection`. |
| 1948 * @param {boolean} [retKey] Specify returning the key of the found element |
| 1949 * instead of the element itself. |
| 1950 * @returns {*} Returns the found element or its key, else `undefined`. |
| 1951 */ |
| 1952 function baseFind(collection, predicate, eachFunc, retKey) { |
| 1953 var result; |
| 1954 eachFunc(collection, function(value, key, collection) { |
| 1955 if (predicate(value, key, collection)) { |
| 1956 result = retKey ? key : value; |
| 1957 return false; |
| 1958 } |
| 1959 }); |
| 1960 return result; |
| 1961 } |
| 1962 |
| 1963 /** |
| 1964 * The base implementation of `_.flatten` with added support for restricting |
| 1965 * flattening and specifying the start index. |
| 1966 * |
| 1967 * @private |
| 1968 * @param {Array} array The array to flatten. |
| 1969 * @param {boolean} [isDeep] Specify a deep flatten. |
| 1970 * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. |
| 1971 * @param {Array} [result=[]] The initial result value. |
| 1972 * @returns {Array} Returns the new flattened array. |
| 1973 */ |
| 1974 function baseFlatten(array, isDeep, isStrict, result) { |
| 1975 result || (result = []); |
| 1976 |
| 1977 var index = -1, |
| 1978 length = array.length; |
| 1979 |
| 1980 while (++index < length) { |
| 1981 var value = array[index]; |
| 1982 if (isObjectLike(value) && isArrayLike(value) && |
| 1983 (isStrict || isArray(value) || isArguments(value))) { |
| 1984 if (isDeep) { |
| 1985 // Recursively flatten arrays (susceptible to call stack limits). |
| 1986 baseFlatten(value, isDeep, isStrict, result); |
| 1987 } else { |
| 1988 arrayPush(result, value); |
| 1989 } |
| 1990 } else if (!isStrict) { |
| 1991 result[result.length] = value; |
| 1992 } |
| 1993 } |
| 1994 return result; |
| 1995 } |
| 1996 |
| 1997 /** |
| 1998 * The base implementation of `baseForIn` and `baseForOwn` which iterates |
| 1999 * over `object` properties returned by `keysFunc` invoking `iteratee` for |
| 2000 * each property. Iteratee functions may exit iteration early by explicitly |
| 2001 * returning `false`. |
| 2002 * |
| 2003 * @private |
| 2004 * @param {Object} object The object to iterate over. |
| 2005 * @param {Function} iteratee The function invoked per iteration. |
| 2006 * @param {Function} keysFunc The function to get the keys of `object`. |
| 2007 * @returns {Object} Returns `object`. |
| 2008 */ |
| 2009 var baseFor = createBaseFor(); |
| 2010 |
| 2011 /** |
| 2012 * This function is like `baseFor` except that it iterates over properties |
| 2013 * in the opposite order. |
| 2014 * |
| 2015 * @private |
| 2016 * @param {Object} object The object to iterate over. |
| 2017 * @param {Function} iteratee The function invoked per iteration. |
| 2018 * @param {Function} keysFunc The function to get the keys of `object`. |
| 2019 * @returns {Object} Returns `object`. |
| 2020 */ |
| 2021 var baseForRight = createBaseFor(true); |
| 2022 |
| 2023 /** |
| 2024 * The base implementation of `_.forIn` without support for callback |
| 2025 * shorthands and `this` binding. |
| 2026 * |
| 2027 * @private |
| 2028 * @param {Object} object The object to iterate over. |
| 2029 * @param {Function} iteratee The function invoked per iteration. |
| 2030 * @returns {Object} Returns `object`. |
| 2031 */ |
| 2032 function baseForIn(object, iteratee) { |
| 2033 return baseFor(object, iteratee, keysIn); |
| 2034 } |
| 2035 |
| 2036 /** |
| 2037 * The base implementation of `_.forOwn` without support for callback |
| 2038 * shorthands and `this` binding. |
| 2039 * |
| 2040 * @private |
| 2041 * @param {Object} object The object to iterate over. |
| 2042 * @param {Function} iteratee The function invoked per iteration. |
| 2043 * @returns {Object} Returns `object`. |
| 2044 */ |
| 2045 function baseForOwn(object, iteratee) { |
| 2046 return baseFor(object, iteratee, keys); |
| 2047 } |
| 2048 |
| 2049 /** |
| 2050 * The base implementation of `_.forOwnRight` without support for callback |
| 2051 * shorthands and `this` binding. |
| 2052 * |
| 2053 * @private |
| 2054 * @param {Object} object The object to iterate over. |
| 2055 * @param {Function} iteratee The function invoked per iteration. |
| 2056 * @returns {Object} Returns `object`. |
| 2057 */ |
| 2058 function baseForOwnRight(object, iteratee) { |
| 2059 return baseForRight(object, iteratee, keys); |
| 2060 } |
| 2061 |
| 2062 /** |
| 2063 * The base implementation of `_.functions` which creates an array of |
| 2064 * `object` function property names filtered from those provided. |
| 2065 * |
| 2066 * @private |
| 2067 * @param {Object} object The object to inspect. |
| 2068 * @param {Array} props The property names to filter. |
| 2069 * @returns {Array} Returns the new array of filtered property names. |
| 2070 */ |
| 2071 function baseFunctions(object, props) { |
| 2072 var index = -1, |
| 2073 length = props.length, |
| 2074 resIndex = -1, |
| 2075 result = []; |
| 2076 |
| 2077 while (++index < length) { |
| 2078 var key = props[index]; |
| 2079 if (isFunction(object[key])) { |
| 2080 result[++resIndex] = key; |
| 2081 } |
| 2082 } |
| 2083 return result; |
| 2084 } |
| 2085 |
| 2086 /** |
| 2087 * The base implementation of `get` without support for string paths |
| 2088 * and default values. |
| 2089 * |
| 2090 * @private |
| 2091 * @param {Object} object The object to query. |
| 2092 * @param {Array} path The path of the property to get. |
| 2093 * @param {string} [pathKey] The key representation of path. |
| 2094 * @returns {*} Returns the resolved value. |
| 2095 */ |
| 2096 function baseGet(object, path, pathKey) { |
| 2097 if (object == null) { |
| 2098 return; |
| 2099 } |
| 2100 if (pathKey !== undefined && pathKey in toObject(object)) { |
| 2101 path = [pathKey]; |
| 2102 } |
| 2103 var index = 0, |
| 2104 length = path.length; |
| 2105 |
| 2106 while (object != null && index < length) { |
| 2107 object = object[path[index++]]; |
| 2108 } |
| 2109 return (index && index == length) ? object : undefined; |
| 2110 } |
| 2111 |
| 2112 /** |
| 2113 * The base implementation of `_.isEqual` without support for `this` binding |
| 2114 * `customizer` functions. |
| 2115 * |
| 2116 * @private |
| 2117 * @param {*} value The value to compare. |
| 2118 * @param {*} other The other value to compare. |
| 2119 * @param {Function} [customizer] The function to customize comparing values
. |
| 2120 * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 2121 * @param {Array} [stackA] Tracks traversed `value` objects. |
| 2122 * @param {Array} [stackB] Tracks traversed `other` objects. |
| 2123 * @returns {boolean} Returns `true` if the values are equivalent, else `fal
se`. |
| 2124 */ |
| 2125 function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { |
| 2126 if (value === other) { |
| 2127 return true; |
| 2128 } |
| 2129 if (value == null || other == null || (!isObject(value) && !isObjectLike(o
ther))) { |
| 2130 return value !== value && other !== other; |
| 2131 } |
| 2132 return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, sta
ckA, stackB); |
| 2133 } |
| 2134 |
| 2135 /** |
| 2136 * A specialized version of `baseIsEqual` for arrays and objects which perfo
rms |
| 2137 * deep comparisons and tracks traversed objects enabling objects with circu
lar |
| 2138 * references to be compared. |
| 2139 * |
| 2140 * @private |
| 2141 * @param {Object} object The object to compare. |
| 2142 * @param {Object} other The other object to compare. |
| 2143 * @param {Function} equalFunc The function to determine equivalents of valu
es. |
| 2144 * @param {Function} [customizer] The function to customize comparing object
s. |
| 2145 * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 2146 * @param {Array} [stackA=[]] Tracks traversed `value` objects. |
| 2147 * @param {Array} [stackB=[]] Tracks traversed `other` objects. |
| 2148 * @returns {boolean} Returns `true` if the objects are equivalent, else `fa
lse`. |
| 2149 */ |
| 2150 function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stac
kA, stackB) { |
| 2151 var objIsArr = isArray(object), |
| 2152 othIsArr = isArray(other), |
| 2153 objTag = arrayTag, |
| 2154 othTag = arrayTag; |
| 2155 |
| 2156 if (!objIsArr) { |
| 2157 objTag = objToString.call(object); |
| 2158 if (objTag == argsTag) { |
| 2159 objTag = objectTag; |
| 2160 } else if (objTag != objectTag) { |
| 2161 objIsArr = isTypedArray(object); |
| 2162 } |
| 2163 } |
| 2164 if (!othIsArr) { |
| 2165 othTag = objToString.call(other); |
| 2166 if (othTag == argsTag) { |
| 2167 othTag = objectTag; |
| 2168 } else if (othTag != objectTag) { |
| 2169 othIsArr = isTypedArray(other); |
| 2170 } |
| 2171 } |
| 2172 var objIsObj = objTag == objectTag, |
| 2173 othIsObj = othTag == objectTag, |
| 2174 isSameTag = objTag == othTag; |
| 2175 |
| 2176 if (isSameTag && !(objIsArr || objIsObj)) { |
| 2177 return equalByTag(object, other, objTag); |
| 2178 } |
| 2179 if (!isLoose) { |
| 2180 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'
), |
| 2181 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__')
; |
| 2182 |
| 2183 if (objIsWrapped || othIsWrapped) { |
| 2184 return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped
? other.value() : other, customizer, isLoose, stackA, stackB); |
| 2185 } |
| 2186 } |
| 2187 if (!isSameTag) { |
| 2188 return false; |
| 2189 } |
| 2190 // Assume cyclic values are equal. |
| 2191 // For more information on detecting circular references see https://es5.g
ithub.io/#JO. |
| 2192 stackA || (stackA = []); |
| 2193 stackB || (stackB = []); |
| 2194 |
| 2195 var length = stackA.length; |
| 2196 while (length--) { |
| 2197 if (stackA[length] == object) { |
| 2198 return stackB[length] == other; |
| 2199 } |
| 2200 } |
| 2201 // Add `object` and `other` to the stack of traversed objects. |
| 2202 stackA.push(object); |
| 2203 stackB.push(other); |
| 2204 |
| 2205 var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalF
unc, customizer, isLoose, stackA, stackB); |
| 2206 |
| 2207 stackA.pop(); |
| 2208 stackB.pop(); |
| 2209 |
| 2210 return result; |
| 2211 } |
| 2212 |
| 2213 /** |
| 2214 * The base implementation of `_.isMatch` without support for callback |
| 2215 * shorthands and `this` binding. |
| 2216 * |
| 2217 * @private |
| 2218 * @param {Object} object The object to inspect. |
| 2219 * @param {Array} matchData The propery names, values, and compare flags to
match. |
| 2220 * @param {Function} [customizer] The function to customize comparing object
s. |
| 2221 * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
| 2222 */ |
| 2223 function baseIsMatch(object, matchData, customizer) { |
| 2224 var index = matchData.length, |
| 2225 length = index, |
| 2226 noCustomizer = !customizer; |
| 2227 |
| 2228 if (object == null) { |
| 2229 return !length; |
| 2230 } |
| 2231 object = toObject(object); |
| 2232 while (index--) { |
| 2233 var data = matchData[index]; |
| 2234 if ((noCustomizer && data[2]) |
| 2235 ? data[1] !== object[data[0]] |
| 2236 : !(data[0] in object) |
| 2237 ) { |
| 2238 return false; |
| 2239 } |
| 2240 } |
| 2241 while (++index < length) { |
| 2242 data = matchData[index]; |
| 2243 var key = data[0], |
| 2244 objValue = object[key], |
| 2245 srcValue = data[1]; |
| 2246 |
| 2247 if (noCustomizer && data[2]) { |
| 2248 if (objValue === undefined && !(key in object)) { |
| 2249 return false; |
| 2250 } |
| 2251 } else { |
| 2252 var result = customizer ? customizer(objValue, srcValue, key) : undefi
ned; |
| 2253 if (!(result === undefined ? baseIsEqual(srcValue, objValue, customize
r, true) : result)) { |
| 2254 return false; |
| 2255 } |
| 2256 } |
| 2257 } |
| 2258 return true; |
| 2259 } |
| 2260 |
| 2261 /** |
| 2262 * The base implementation of `_.map` without support for callback shorthand
s |
| 2263 * and `this` binding. |
| 2264 * |
| 2265 * @private |
| 2266 * @param {Array|Object|string} collection The collection to iterate over. |
| 2267 * @param {Function} iteratee The function invoked per iteration. |
| 2268 * @returns {Array} Returns the new mapped array. |
| 2269 */ |
| 2270 function baseMap(collection, iteratee) { |
| 2271 var index = -1, |
| 2272 result = isArrayLike(collection) ? Array(collection.length) : []; |
| 2273 |
| 2274 baseEach(collection, function(value, key, collection) { |
| 2275 result[++index] = iteratee(value, key, collection); |
| 2276 }); |
| 2277 return result; |
| 2278 } |
| 2279 |
| 2280 /** |
| 2281 * The base implementation of `_.matches` which does not clone `source`. |
| 2282 * |
| 2283 * @private |
| 2284 * @param {Object} source The object of property values to match. |
| 2285 * @returns {Function} Returns the new function. |
| 2286 */ |
| 2287 function baseMatches(source) { |
| 2288 var matchData = getMatchData(source); |
| 2289 if (matchData.length == 1 && matchData[0][2]) { |
| 2290 var key = matchData[0][0], |
| 2291 value = matchData[0][1]; |
| 2292 |
| 2293 return function(object) { |
| 2294 if (object == null) { |
| 2295 return false; |
| 2296 } |
| 2297 return object[key] === value && (value !== undefined || (key in toObje
ct(object))); |
| 2298 }; |
| 2299 } |
| 2300 return function(object) { |
| 2301 return baseIsMatch(object, matchData); |
| 2302 }; |
| 2303 } |
| 2304 |
| 2305 /** |
| 2306 * The base implementation of `_.matchesProperty` which does not clone `srcV
alue`. |
| 2307 * |
| 2308 * @private |
| 2309 * @param {string} path The path of the property to get. |
| 2310 * @param {*} srcValue The value to compare. |
| 2311 * @returns {Function} Returns the new function. |
| 2312 */ |
| 2313 function baseMatchesProperty(path, srcValue) { |
| 2314 var isArr = isArray(path), |
| 2315 isCommon = isKey(path) && isStrictComparable(srcValue), |
| 2316 pathKey = (path + ''); |
| 2317 |
| 2318 path = toPath(path); |
| 2319 return function(object) { |
| 2320 if (object == null) { |
| 2321 return false; |
| 2322 } |
| 2323 var key = pathKey; |
| 2324 object = toObject(object); |
| 2325 if ((isArr || !isCommon) && !(key in object)) { |
| 2326 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0
, -1)); |
| 2327 if (object == null) { |
| 2328 return false; |
| 2329 } |
| 2330 key = last(path); |
| 2331 object = toObject(object); |
| 2332 } |
| 2333 return object[key] === srcValue |
| 2334 ? (srcValue !== undefined || (key in object)) |
| 2335 : baseIsEqual(srcValue, object[key], undefined, true); |
| 2336 }; |
| 2337 } |
| 2338 |
| 2339 /** |
| 2340 * The base implementation of `_.merge` without support for argument jugglin
g, |
| 2341 * multiple sources, and `this` binding `customizer` functions. |
| 2342 * |
| 2343 * @private |
| 2344 * @param {Object} object The destination object. |
| 2345 * @param {Object} source The source object. |
| 2346 * @param {Function} [customizer] The function to customize merged values. |
| 2347 * @param {Array} [stackA=[]] Tracks traversed source objects. |
| 2348 * @param {Array} [stackB=[]] Associates values with source counterparts. |
| 2349 * @returns {Object} Returns `object`. |
| 2350 */ |
| 2351 function baseMerge(object, source, customizer, stackA, stackB) { |
| 2352 if (!isObject(object)) { |
| 2353 return object; |
| 2354 } |
| 2355 var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(sou
rce)), |
| 2356 props = isSrcArr ? undefined : keys(source); |
| 2357 |
| 2358 arrayEach(props || source, function(srcValue, key) { |
| 2359 if (props) { |
| 2360 key = srcValue; |
| 2361 srcValue = source[key]; |
| 2362 } |
| 2363 if (isObjectLike(srcValue)) { |
| 2364 stackA || (stackA = []); |
| 2365 stackB || (stackB = []); |
| 2366 baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stac
kB); |
| 2367 } |
| 2368 else { |
| 2369 var value = object[key], |
| 2370 result = customizer ? customizer(value, srcValue, key, object, sou
rce) : undefined, |
| 2371 isCommon = result === undefined; |
| 2372 |
| 2373 if (isCommon) { |
| 2374 result = srcValue; |
| 2375 } |
| 2376 if ((result !== undefined || (isSrcArr && !(key in object))) && |
| 2377 (isCommon || (result === result ? (result !== value) : (value ===
value)))) { |
| 2378 object[key] = result; |
| 2379 } |
| 2380 } |
| 2381 }); |
| 2382 return object; |
| 2383 } |
| 2384 |
| 2385 /** |
| 2386 * A specialized version of `baseMerge` for arrays and objects which perform
s |
| 2387 * deep merges and tracks traversed objects enabling objects with circular |
| 2388 * references to be merged. |
| 2389 * |
| 2390 * @private |
| 2391 * @param {Object} object The destination object. |
| 2392 * @param {Object} source The source object. |
| 2393 * @param {string} key The key of the value to merge. |
| 2394 * @param {Function} mergeFunc The function to merge values. |
| 2395 * @param {Function} [customizer] The function to customize merged values. |
| 2396 * @param {Array} [stackA=[]] Tracks traversed source objects. |
| 2397 * @param {Array} [stackB=[]] Associates values with source counterparts. |
| 2398 * @returns {boolean} Returns `true` if the objects are equivalent, else `fa
lse`. |
| 2399 */ |
| 2400 function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, s
tackB) { |
| 2401 var length = stackA.length, |
| 2402 srcValue = source[key]; |
| 2403 |
| 2404 while (length--) { |
| 2405 if (stackA[length] == srcValue) { |
| 2406 object[key] = stackB[length]; |
| 2407 return; |
| 2408 } |
| 2409 } |
| 2410 var value = object[key], |
| 2411 result = customizer ? customizer(value, srcValue, key, object, source)
: undefined, |
| 2412 isCommon = result === undefined; |
| 2413 |
| 2414 if (isCommon) { |
| 2415 result = srcValue; |
| 2416 if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue
))) { |
| 2417 result = isArray(value) |
| 2418 ? value |
| 2419 : (isArrayLike(value) ? arrayCopy(value) : []); |
| 2420 } |
| 2421 else if (isPlainObject(srcValue) || isArguments(srcValue)) { |
| 2422 result = isArguments(value) |
| 2423 ? toPlainObject(value) |
| 2424 : (isPlainObject(value) ? value : {}); |
| 2425 } |
| 2426 else { |
| 2427 isCommon = false; |
| 2428 } |
| 2429 } |
| 2430 // Add the source value to the stack of traversed objects and associate |
| 2431 // it with its merged value. |
| 2432 stackA.push(srcValue); |
| 2433 stackB.push(result); |
| 2434 |
| 2435 if (isCommon) { |
| 2436 // Recursively merge objects and arrays (susceptible to call stack limit
s). |
| 2437 object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); |
| 2438 } else if (result === result ? (result !== value) : (value === value)) { |
| 2439 object[key] = result; |
| 2440 } |
| 2441 } |
| 2442 |
| 2443 /** |
| 2444 * The base implementation of `_.property` without support for deep paths. |
| 2445 * |
| 2446 * @private |
| 2447 * @param {string} key The key of the property to get. |
| 2448 * @returns {Function} Returns the new function. |
| 2449 */ |
| 2450 function baseProperty(key) { |
| 2451 return function(object) { |
| 2452 return object == null ? undefined : object[key]; |
| 2453 }; |
| 2454 } |
| 2455 |
| 2456 /** |
| 2457 * A specialized version of `baseProperty` which supports deep paths. |
| 2458 * |
| 2459 * @private |
| 2460 * @param {Array|string} path The path of the property to get. |
| 2461 * @returns {Function} Returns the new function. |
| 2462 */ |
| 2463 function basePropertyDeep(path) { |
| 2464 var pathKey = (path + ''); |
| 2465 path = toPath(path); |
| 2466 return function(object) { |
| 2467 return baseGet(object, path, pathKey); |
| 2468 }; |
| 2469 } |
| 2470 |
| 2471 /** |
| 2472 * The base implementation of `_.pullAt` without support for individual |
| 2473 * index arguments and capturing the removed elements. |
| 2474 * |
| 2475 * @private |
| 2476 * @param {Array} array The array to modify. |
| 2477 * @param {number[]} indexes The indexes of elements to remove. |
| 2478 * @returns {Array} Returns `array`. |
| 2479 */ |
| 2480 function basePullAt(array, indexes) { |
| 2481 var length = array ? indexes.length : 0; |
| 2482 while (length--) { |
| 2483 var index = indexes[length]; |
| 2484 if (index != previous && isIndex(index)) { |
| 2485 var previous = index; |
| 2486 splice.call(array, index, 1); |
| 2487 } |
| 2488 } |
| 2489 return array; |
| 2490 } |
| 2491 |
| 2492 /** |
| 2493 * The base implementation of `_.random` without support for argument juggli
ng |
| 2494 * and returning floating-point numbers. |
| 2495 * |
| 2496 * @private |
| 2497 * @param {number} min The minimum possible value. |
| 2498 * @param {number} max The maximum possible value. |
| 2499 * @returns {number} Returns the random number. |
| 2500 */ |
| 2501 function baseRandom(min, max) { |
| 2502 return min + nativeFloor(nativeRandom() * (max - min + 1)); |
| 2503 } |
| 2504 |
| 2505 /** |
| 2506 * The base implementation of `_.reduce` and `_.reduceRight` without support |
| 2507 * for callback shorthands and `this` binding, which iterates over `collecti
on` |
| 2508 * using the provided `eachFunc`. |
| 2509 * |
| 2510 * @private |
| 2511 * @param {Array|Object|string} collection The collection to iterate over. |
| 2512 * @param {Function} iteratee The function invoked per iteration. |
| 2513 * @param {*} accumulator The initial value. |
| 2514 * @param {boolean} initFromCollection Specify using the first or last eleme
nt |
| 2515 * of `collection` as the initial value. |
| 2516 * @param {Function} eachFunc The function to iterate over `collection`. |
| 2517 * @returns {*} Returns the accumulated value. |
| 2518 */ |
| 2519 function baseReduce(collection, iteratee, accumulator, initFromCollection, e
achFunc) { |
| 2520 eachFunc(collection, function(value, index, collection) { |
| 2521 accumulator = initFromCollection |
| 2522 ? (initFromCollection = false, value) |
| 2523 : iteratee(accumulator, value, index, collection); |
| 2524 }); |
| 2525 return accumulator; |
| 2526 } |
| 2527 |
| 2528 /** |
| 2529 * The base implementation of `setData` without support for hot loop detecti
on. |
| 2530 * |
| 2531 * @private |
| 2532 * @param {Function} func The function to associate metadata with. |
| 2533 * @param {*} data The metadata. |
| 2534 * @returns {Function} Returns `func`. |
| 2535 */ |
| 2536 var baseSetData = !metaMap ? identity : function(func, data) { |
| 2537 metaMap.set(func, data); |
| 2538 return func; |
| 2539 }; |
| 2540 |
| 2541 /** |
| 2542 * The base implementation of `_.slice` without an iteratee call guard. |
| 2543 * |
| 2544 * @private |
| 2545 * @param {Array} array The array to slice. |
| 2546 * @param {number} [start=0] The start position. |
| 2547 * @param {number} [end=array.length] The end position. |
| 2548 * @returns {Array} Returns the slice of `array`. |
| 2549 */ |
| 2550 function baseSlice(array, start, end) { |
| 2551 var index = -1, |
| 2552 length = array.length; |
| 2553 |
| 2554 start = start == null ? 0 : (+start || 0); |
| 2555 if (start < 0) { |
| 2556 start = -start > length ? 0 : (length + start); |
| 2557 } |
| 2558 end = (end === undefined || end > length) ? length : (+end || 0); |
| 2559 if (end < 0) { |
| 2560 end += length; |
| 2561 } |
| 2562 length = start > end ? 0 : ((end - start) >>> 0); |
| 2563 start >>>= 0; |
| 2564 |
| 2565 var result = Array(length); |
| 2566 while (++index < length) { |
| 2567 result[index] = array[index + start]; |
| 2568 } |
| 2569 return result; |
| 2570 } |
| 2571 |
| 2572 /** |
| 2573 * The base implementation of `_.some` without support for callback shorthan
ds |
| 2574 * and `this` binding. |
| 2575 * |
| 2576 * @private |
| 2577 * @param {Array|Object|string} collection The collection to iterate over. |
| 2578 * @param {Function} predicate The function invoked per iteration. |
| 2579 * @returns {boolean} Returns `true` if any element passes the predicate che
ck, |
| 2580 * else `false`. |
| 2581 */ |
| 2582 function baseSome(collection, predicate) { |
| 2583 var result; |
| 2584 |
| 2585 baseEach(collection, function(value, index, collection) { |
| 2586 result = predicate(value, index, collection); |
| 2587 return !result; |
| 2588 }); |
| 2589 return !!result; |
| 2590 } |
| 2591 |
| 2592 /** |
| 2593 * The base implementation of `_.sortBy` which uses `comparer` to define |
| 2594 * the sort order of `array` and replaces criteria objects with their |
| 2595 * corresponding values. |
| 2596 * |
| 2597 * @private |
| 2598 * @param {Array} array The array to sort. |
| 2599 * @param {Function} comparer The function to define sort order. |
| 2600 * @returns {Array} Returns `array`. |
| 2601 */ |
| 2602 function baseSortBy(array, comparer) { |
| 2603 var length = array.length; |
| 2604 |
| 2605 array.sort(comparer); |
| 2606 while (length--) { |
| 2607 array[length] = array[length].value; |
| 2608 } |
| 2609 return array; |
| 2610 } |
| 2611 |
| 2612 /** |
| 2613 * The base implementation of `_.sortByOrder` without param guards. |
| 2614 * |
| 2615 * @private |
| 2616 * @param {Array|Object|string} collection The collection to iterate over. |
| 2617 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. |
| 2618 * @param {boolean[]} orders The sort orders of `iteratees`. |
| 2619 * @returns {Array} Returns the new sorted array. |
| 2620 */ |
| 2621 function baseSortByOrder(collection, iteratees, orders) { |
| 2622 var callback = getCallback(), |
| 2623 index = -1; |
| 2624 |
| 2625 iteratees = arrayMap(iteratees, function(iteratee) { return callback(itera
tee); }); |
| 2626 |
| 2627 var result = baseMap(collection, function(value) { |
| 2628 var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(
value); }); |
| 2629 return { 'criteria': criteria, 'index': ++index, 'value': value }; |
| 2630 }); |
| 2631 |
| 2632 return baseSortBy(result, function(object, other) { |
| 2633 return compareMultiple(object, other, orders); |
| 2634 }); |
| 2635 } |
| 2636 |
| 2637 /** |
| 2638 * The base implementation of `_.sum` without support for callback shorthand
s |
| 2639 * and `this` binding. |
| 2640 * |
| 2641 * @private |
| 2642 * @param {Array|Object|string} collection The collection to iterate over. |
| 2643 * @param {Function} iteratee The function invoked per iteration. |
| 2644 * @returns {number} Returns the sum. |
| 2645 */ |
| 2646 function baseSum(collection, iteratee) { |
| 2647 var result = 0; |
| 2648 baseEach(collection, function(value, index, collection) { |
| 2649 result += +iteratee(value, index, collection) || 0; |
| 2650 }); |
| 2651 return result; |
| 2652 } |
| 2653 |
| 2654 /** |
| 2655 * The base implementation of `_.uniq` without support for callback shorthan
ds |
| 2656 * and `this` binding. |
| 2657 * |
| 2658 * @private |
| 2659 * @param {Array} array The array to inspect. |
| 2660 * @param {Function} [iteratee] The function invoked per iteration. |
| 2661 * @returns {Array} Returns the new duplicate free array. |
| 2662 */ |
| 2663 function baseUniq(array, iteratee) { |
| 2664 var index = -1, |
| 2665 indexOf = getIndexOf(), |
| 2666 length = array.length, |
| 2667 isCommon = indexOf === baseIndexOf, |
| 2668 isLarge = isCommon && length >= LARGE_ARRAY_SIZE, |
| 2669 seen = isLarge ? createCache() : null, |
| 2670 result = []; |
| 2671 |
| 2672 if (seen) { |
| 2673 indexOf = cacheIndexOf; |
| 2674 isCommon = false; |
| 2675 } else { |
| 2676 isLarge = false; |
| 2677 seen = iteratee ? [] : result; |
| 2678 } |
| 2679 outer: |
| 2680 while (++index < length) { |
| 2681 var value = array[index], |
| 2682 computed = iteratee ? iteratee(value, index, array) : value; |
| 2683 |
| 2684 if (isCommon && value === value) { |
| 2685 var seenIndex = seen.length; |
| 2686 while (seenIndex--) { |
| 2687 if (seen[seenIndex] === computed) { |
| 2688 continue outer; |
| 2689 } |
| 2690 } |
| 2691 if (iteratee) { |
| 2692 seen.push(computed); |
| 2693 } |
| 2694 result.push(value); |
| 2695 } |
| 2696 else if (indexOf(seen, computed, 0) < 0) { |
| 2697 if (iteratee || isLarge) { |
| 2698 seen.push(computed); |
| 2699 } |
| 2700 result.push(value); |
| 2701 } |
| 2702 } |
| 2703 return result; |
| 2704 } |
| 2705 |
| 2706 /** |
| 2707 * The base implementation of `_.values` and `_.valuesIn` which creates an |
| 2708 * array of `object` property values corresponding to the property names |
| 2709 * of `props`. |
| 2710 * |
| 2711 * @private |
| 2712 * @param {Object} object The object to query. |
| 2713 * @param {Array} props The property names to get values for. |
| 2714 * @returns {Object} Returns the array of property values. |
| 2715 */ |
| 2716 function baseValues(object, props) { |
| 2717 var index = -1, |
| 2718 length = props.length, |
| 2719 result = Array(length); |
| 2720 |
| 2721 while (++index < length) { |
| 2722 result[index] = object[props[index]]; |
| 2723 } |
| 2724 return result; |
| 2725 } |
| 2726 |
| 2727 /** |
| 2728 * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRigh
tWhile`, |
| 2729 * and `_.takeWhile` without support for callback shorthands and `this` bind
ing. |
| 2730 * |
| 2731 * @private |
| 2732 * @param {Array} array The array to query. |
| 2733 * @param {Function} predicate The function invoked per iteration. |
| 2734 * @param {boolean} [isDrop] Specify dropping elements instead of taking the
m. |
| 2735 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 2736 * @returns {Array} Returns the slice of `array`. |
| 2737 */ |
| 2738 function baseWhile(array, predicate, isDrop, fromRight) { |
| 2739 var length = array.length, |
| 2740 index = fromRight ? length : -1; |
| 2741 |
| 2742 while ((fromRight ? index-- : ++index < length) && predicate(array[index],
index, array)) {} |
| 2743 return isDrop |
| 2744 ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : len
gth)) |
| 2745 : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : in
dex)); |
| 2746 } |
| 2747 |
| 2748 /** |
| 2749 * The base implementation of `wrapperValue` which returns the result of |
| 2750 * performing a sequence of actions on the unwrapped `value`, where each |
| 2751 * successive action is supplied the return value of the previous. |
| 2752 * |
| 2753 * @private |
| 2754 * @param {*} value The unwrapped value. |
| 2755 * @param {Array} actions Actions to peform to resolve the unwrapped value. |
| 2756 * @returns {*} Returns the resolved value. |
| 2757 */ |
| 2758 function baseWrapperValue(value, actions) { |
| 2759 var result = value; |
| 2760 if (result instanceof LazyWrapper) { |
| 2761 result = result.value(); |
| 2762 } |
| 2763 var index = -1, |
| 2764 length = actions.length; |
| 2765 |
| 2766 while (++index < length) { |
| 2767 var action = actions[index]; |
| 2768 result = action.func.apply(action.thisArg, arrayPush([result], action.ar
gs)); |
| 2769 } |
| 2770 return result; |
| 2771 } |
| 2772 |
| 2773 /** |
| 2774 * Performs a binary search of `array` to determine the index at which `valu
e` |
| 2775 * should be inserted into `array` in order to maintain its sort order. |
| 2776 * |
| 2777 * @private |
| 2778 * @param {Array} array The sorted array to inspect. |
| 2779 * @param {*} value The value to evaluate. |
| 2780 * @param {boolean} [retHighest] Specify returning the highest qualified ind
ex. |
| 2781 * @returns {number} Returns the index at which `value` should be inserted |
| 2782 * into `array`. |
| 2783 */ |
| 2784 function binaryIndex(array, value, retHighest) { |
| 2785 var low = 0, |
| 2786 high = array ? array.length : low; |
| 2787 |
| 2788 if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_
LENGTH) { |
| 2789 while (low < high) { |
| 2790 var mid = (low + high) >>> 1, |
| 2791 computed = array[mid]; |
| 2792 |
| 2793 if ((retHighest ? (computed <= value) : (computed < value)) && compute
d !== null) { |
| 2794 low = mid + 1; |
| 2795 } else { |
| 2796 high = mid; |
| 2797 } |
| 2798 } |
| 2799 return high; |
| 2800 } |
| 2801 return binaryIndexBy(array, value, identity, retHighest); |
| 2802 } |
| 2803 |
| 2804 /** |
| 2805 * This function is like `binaryIndex` except that it invokes `iteratee` for |
| 2806 * `value` and each element of `array` to compute their sort ranking. The |
| 2807 * iteratee is invoked with one argument; (value). |
| 2808 * |
| 2809 * @private |
| 2810 * @param {Array} array The sorted array to inspect. |
| 2811 * @param {*} value The value to evaluate. |
| 2812 * @param {Function} iteratee The function invoked per iteration. |
| 2813 * @param {boolean} [retHighest] Specify returning the highest qualified ind
ex. |
| 2814 * @returns {number} Returns the index at which `value` should be inserted |
| 2815 * into `array`. |
| 2816 */ |
| 2817 function binaryIndexBy(array, value, iteratee, retHighest) { |
| 2818 value = iteratee(value); |
| 2819 |
| 2820 var low = 0, |
| 2821 high = array ? array.length : 0, |
| 2822 valIsNaN = value !== value, |
| 2823 valIsNull = value === null, |
| 2824 valIsUndef = value === undefined; |
| 2825 |
| 2826 while (low < high) { |
| 2827 var mid = nativeFloor((low + high) / 2), |
| 2828 computed = iteratee(array[mid]), |
| 2829 isDef = computed !== undefined, |
| 2830 isReflexive = computed === computed; |
| 2831 |
| 2832 if (valIsNaN) { |
| 2833 var setLow = isReflexive || retHighest; |
| 2834 } else if (valIsNull) { |
| 2835 setLow = isReflexive && isDef && (retHighest || computed != null); |
| 2836 } else if (valIsUndef) { |
| 2837 setLow = isReflexive && (retHighest || isDef); |
| 2838 } else if (computed == null) { |
| 2839 setLow = false; |
| 2840 } else { |
| 2841 setLow = retHighest ? (computed <= value) : (computed < value); |
| 2842 } |
| 2843 if (setLow) { |
| 2844 low = mid + 1; |
| 2845 } else { |
| 2846 high = mid; |
| 2847 } |
| 2848 } |
| 2849 return nativeMin(high, MAX_ARRAY_INDEX); |
| 2850 } |
| 2851 |
| 2852 /** |
| 2853 * A specialized version of `baseCallback` which only supports `this` bindin
g |
| 2854 * and specifying the number of arguments to provide to `func`. |
| 2855 * |
| 2856 * @private |
| 2857 * @param {Function} func The function to bind. |
| 2858 * @param {*} thisArg The `this` binding of `func`. |
| 2859 * @param {number} [argCount] The number of arguments to provide to `func`. |
| 2860 * @returns {Function} Returns the callback. |
| 2861 */ |
| 2862 function bindCallback(func, thisArg, argCount) { |
| 2863 if (typeof func != 'function') { |
| 2864 return identity; |
| 2865 } |
| 2866 if (thisArg === undefined) { |
| 2867 return func; |
| 2868 } |
| 2869 switch (argCount) { |
| 2870 case 1: return function(value) { |
| 2871 return func.call(thisArg, value); |
| 2872 }; |
| 2873 case 3: return function(value, index, collection) { |
| 2874 return func.call(thisArg, value, index, collection); |
| 2875 }; |
| 2876 case 4: return function(accumulator, value, index, collection) { |
| 2877 return func.call(thisArg, accumulator, value, index, collection); |
| 2878 }; |
| 2879 case 5: return function(value, other, key, object, source) { |
| 2880 return func.call(thisArg, value, other, key, object, source); |
| 2881 }; |
| 2882 } |
| 2883 return function() { |
| 2884 return func.apply(thisArg, arguments); |
| 2885 }; |
| 2886 } |
| 2887 |
| 2888 /** |
| 2889 * Creates a clone of the given array buffer. |
| 2890 * |
| 2891 * @private |
| 2892 * @param {ArrayBuffer} buffer The array buffer to clone. |
| 2893 * @returns {ArrayBuffer} Returns the cloned array buffer. |
| 2894 */ |
| 2895 function bufferClone(buffer) { |
| 2896 var result = new ArrayBuffer(buffer.byteLength), |
| 2897 view = new Uint8Array(result); |
| 2898 |
| 2899 view.set(new Uint8Array(buffer)); |
| 2900 return result; |
| 2901 } |
| 2902 |
| 2903 /** |
| 2904 * Creates an array that is the composition of partially applied arguments, |
| 2905 * placeholders, and provided arguments into a single array of arguments. |
| 2906 * |
| 2907 * @private |
| 2908 * @param {Array|Object} args The provided arguments. |
| 2909 * @param {Array} partials The arguments to prepend to those provided. |
| 2910 * @param {Array} holders The `partials` placeholder indexes. |
| 2911 * @returns {Array} Returns the new array of composed arguments. |
| 2912 */ |
| 2913 function composeArgs(args, partials, holders) { |
| 2914 var holdersLength = holders.length, |
| 2915 argsIndex = -1, |
| 2916 argsLength = nativeMax(args.length - holdersLength, 0), |
| 2917 leftIndex = -1, |
| 2918 leftLength = partials.length, |
| 2919 result = Array(leftLength + argsLength); |
| 2920 |
| 2921 while (++leftIndex < leftLength) { |
| 2922 result[leftIndex] = partials[leftIndex]; |
| 2923 } |
| 2924 while (++argsIndex < holdersLength) { |
| 2925 result[holders[argsIndex]] = args[argsIndex]; |
| 2926 } |
| 2927 while (argsLength--) { |
| 2928 result[leftIndex++] = args[argsIndex++]; |
| 2929 } |
| 2930 return result; |
| 2931 } |
| 2932 |
| 2933 /** |
| 2934 * This function is like `composeArgs` except that the arguments composition |
| 2935 * is tailored for `_.partialRight`. |
| 2936 * |
| 2937 * @private |
| 2938 * @param {Array|Object} args The provided arguments. |
| 2939 * @param {Array} partials The arguments to append to those provided. |
| 2940 * @param {Array} holders The `partials` placeholder indexes. |
| 2941 * @returns {Array} Returns the new array of composed arguments. |
| 2942 */ |
| 2943 function composeArgsRight(args, partials, holders) { |
| 2944 var holdersIndex = -1, |
| 2945 holdersLength = holders.length, |
| 2946 argsIndex = -1, |
| 2947 argsLength = nativeMax(args.length - holdersLength, 0), |
| 2948 rightIndex = -1, |
| 2949 rightLength = partials.length, |
| 2950 result = Array(argsLength + rightLength); |
| 2951 |
| 2952 while (++argsIndex < argsLength) { |
| 2953 result[argsIndex] = args[argsIndex]; |
| 2954 } |
| 2955 var offset = argsIndex; |
| 2956 while (++rightIndex < rightLength) { |
| 2957 result[offset + rightIndex] = partials[rightIndex]; |
| 2958 } |
| 2959 while (++holdersIndex < holdersLength) { |
| 2960 result[offset + holders[holdersIndex]] = args[argsIndex++]; |
| 2961 } |
| 2962 return result; |
| 2963 } |
| 2964 |
| 2965 /** |
| 2966 * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` functio
n. |
| 2967 * |
| 2968 * @private |
| 2969 * @param {Function} setter The function to set keys and values of the accum
ulator object. |
| 2970 * @param {Function} [initializer] The function to initialize the accumulato
r object. |
| 2971 * @returns {Function} Returns the new aggregator function. |
| 2972 */ |
| 2973 function createAggregator(setter, initializer) { |
| 2974 return function(collection, iteratee, thisArg) { |
| 2975 var result = initializer ? initializer() : {}; |
| 2976 iteratee = getCallback(iteratee, thisArg, 3); |
| 2977 |
| 2978 if (isArray(collection)) { |
| 2979 var index = -1, |
| 2980 length = collection.length; |
| 2981 |
| 2982 while (++index < length) { |
| 2983 var value = collection[index]; |
| 2984 setter(result, value, iteratee(value, index, collection), collection
); |
| 2985 } |
| 2986 } else { |
| 2987 baseEach(collection, function(value, key, collection) { |
| 2988 setter(result, value, iteratee(value, key, collection), collection); |
| 2989 }); |
| 2990 } |
| 2991 return result; |
| 2992 }; |
| 2993 } |
| 2994 |
| 2995 /** |
| 2996 * Creates a `_.assign`, `_.defaults`, or `_.merge` function. |
| 2997 * |
| 2998 * @private |
| 2999 * @param {Function} assigner The function to assign values. |
| 3000 * @returns {Function} Returns the new assigner function. |
| 3001 */ |
| 3002 function createAssigner(assigner) { |
| 3003 return restParam(function(object, sources) { |
| 3004 var index = -1, |
| 3005 length = object == null ? 0 : sources.length, |
| 3006 customizer = length > 2 ? sources[length - 2] : undefined, |
| 3007 guard = length > 2 ? sources[2] : undefined, |
| 3008 thisArg = length > 1 ? sources[length - 1] : undefined; |
| 3009 |
| 3010 if (typeof customizer == 'function') { |
| 3011 customizer = bindCallback(customizer, thisArg, 5); |
| 3012 length -= 2; |
| 3013 } else { |
| 3014 customizer = typeof thisArg == 'function' ? thisArg : undefined; |
| 3015 length -= (customizer ? 1 : 0); |
| 3016 } |
| 3017 if (guard && isIterateeCall(sources[0], sources[1], guard)) { |
| 3018 customizer = length < 3 ? undefined : customizer; |
| 3019 length = 1; |
| 3020 } |
| 3021 while (++index < length) { |
| 3022 var source = sources[index]; |
| 3023 if (source) { |
| 3024 assigner(object, source, customizer); |
| 3025 } |
| 3026 } |
| 3027 return object; |
| 3028 }); |
| 3029 } |
| 3030 |
| 3031 /** |
| 3032 * Creates a `baseEach` or `baseEachRight` function. |
| 3033 * |
| 3034 * @private |
| 3035 * @param {Function} eachFunc The function to iterate over a collection. |
| 3036 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 3037 * @returns {Function} Returns the new base function. |
| 3038 */ |
| 3039 function createBaseEach(eachFunc, fromRight) { |
| 3040 return function(collection, iteratee) { |
| 3041 var length = collection ? getLength(collection) : 0; |
| 3042 if (!isLength(length)) { |
| 3043 return eachFunc(collection, iteratee); |
| 3044 } |
| 3045 var index = fromRight ? length : -1, |
| 3046 iterable = toObject(collection); |
| 3047 |
| 3048 while ((fromRight ? index-- : ++index < length)) { |
| 3049 if (iteratee(iterable[index], index, iterable) === false) { |
| 3050 break; |
| 3051 } |
| 3052 } |
| 3053 return collection; |
| 3054 }; |
| 3055 } |
| 3056 |
| 3057 /** |
| 3058 * Creates a base function for `_.forIn` or `_.forInRight`. |
| 3059 * |
| 3060 * @private |
| 3061 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 3062 * @returns {Function} Returns the new base function. |
| 3063 */ |
| 3064 function createBaseFor(fromRight) { |
| 3065 return function(object, iteratee, keysFunc) { |
| 3066 var iterable = toObject(object), |
| 3067 props = keysFunc(object), |
| 3068 length = props.length, |
| 3069 index = fromRight ? length : -1; |
| 3070 |
| 3071 while ((fromRight ? index-- : ++index < length)) { |
| 3072 var key = props[index]; |
| 3073 if (iteratee(iterable[key], key, iterable) === false) { |
| 3074 break; |
| 3075 } |
| 3076 } |
| 3077 return object; |
| 3078 }; |
| 3079 } |
| 3080 |
| 3081 /** |
| 3082 * Creates a function that wraps `func` and invokes it with the `this` |
| 3083 * binding of `thisArg`. |
| 3084 * |
| 3085 * @private |
| 3086 * @param {Function} func The function to bind. |
| 3087 * @param {*} [thisArg] The `this` binding of `func`. |
| 3088 * @returns {Function} Returns the new bound function. |
| 3089 */ |
| 3090 function createBindWrapper(func, thisArg) { |
| 3091 var Ctor = createCtorWrapper(func); |
| 3092 |
| 3093 function wrapper() { |
| 3094 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : fun
c; |
| 3095 return fn.apply(thisArg, arguments); |
| 3096 } |
| 3097 return wrapper; |
| 3098 } |
| 3099 |
| 3100 /** |
| 3101 * Creates a `Set` cache object to optimize linear searches of large arrays. |
| 3102 * |
| 3103 * @private |
| 3104 * @param {Array} [values] The values to cache. |
| 3105 * @returns {null|Object} Returns the new cache object if `Set` is supported
, else `null`. |
| 3106 */ |
| 3107 function createCache(values) { |
| 3108 return (nativeCreate && Set) ? new SetCache(values) : null; |
| 3109 } |
| 3110 |
| 3111 /** |
| 3112 * Creates a function that produces compound words out of the words in a |
| 3113 * given string. |
| 3114 * |
| 3115 * @private |
| 3116 * @param {Function} callback The function to combine each word. |
| 3117 * @returns {Function} Returns the new compounder function. |
| 3118 */ |
| 3119 function createCompounder(callback) { |
| 3120 return function(string) { |
| 3121 var index = -1, |
| 3122 array = words(deburr(string)), |
| 3123 length = array.length, |
| 3124 result = ''; |
| 3125 |
| 3126 while (++index < length) { |
| 3127 result = callback(result, array[index], index); |
| 3128 } |
| 3129 return result; |
| 3130 }; |
| 3131 } |
| 3132 |
| 3133 /** |
| 3134 * Creates a function that produces an instance of `Ctor` regardless of |
| 3135 * whether it was invoked as part of a `new` expression or by `call` or `app
ly`. |
| 3136 * |
| 3137 * @private |
| 3138 * @param {Function} Ctor The constructor to wrap. |
| 3139 * @returns {Function} Returns the new wrapped function. |
| 3140 */ |
| 3141 function createCtorWrapper(Ctor) { |
| 3142 return function() { |
| 3143 // Use a `switch` statement to work with class constructors. |
| 3144 // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-functi
on-objects-call-thisargument-argumentslist |
| 3145 // for more details. |
| 3146 var args = arguments; |
| 3147 switch (args.length) { |
| 3148 case 0: return new Ctor; |
| 3149 case 1: return new Ctor(args[0]); |
| 3150 case 2: return new Ctor(args[0], args[1]); |
| 3151 case 3: return new Ctor(args[0], args[1], args[2]); |
| 3152 case 4: return new Ctor(args[0], args[1], args[2], args[3]); |
| 3153 case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); |
| 3154 case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], a
rgs[5]); |
| 3155 case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], a
rgs[5], args[6]); |
| 3156 } |
| 3157 var thisBinding = baseCreate(Ctor.prototype), |
| 3158 result = Ctor.apply(thisBinding, args); |
| 3159 |
| 3160 // Mimic the constructor's `return` behavior. |
| 3161 // See https://es5.github.io/#x13.2.2 for more details. |
| 3162 return isObject(result) ? result : thisBinding; |
| 3163 }; |
| 3164 } |
| 3165 |
| 3166 /** |
| 3167 * Creates a `_.curry` or `_.curryRight` function. |
| 3168 * |
| 3169 * @private |
| 3170 * @param {boolean} flag The curry bit flag. |
| 3171 * @returns {Function} Returns the new curry function. |
| 3172 */ |
| 3173 function createCurry(flag) { |
| 3174 function curryFunc(func, arity, guard) { |
| 3175 if (guard && isIterateeCall(func, arity, guard)) { |
| 3176 arity = undefined; |
| 3177 } |
| 3178 var result = createWrapper(func, flag, undefined, undefined, undefined,
undefined, undefined, arity); |
| 3179 result.placeholder = curryFunc.placeholder; |
| 3180 return result; |
| 3181 } |
| 3182 return curryFunc; |
| 3183 } |
| 3184 |
| 3185 /** |
| 3186 * Creates a `_.defaults` or `_.defaultsDeep` function. |
| 3187 * |
| 3188 * @private |
| 3189 * @param {Function} assigner The function to assign values. |
| 3190 * @param {Function} customizer The function to customize assigned values. |
| 3191 * @returns {Function} Returns the new defaults function. |
| 3192 */ |
| 3193 function createDefaults(assigner, customizer) { |
| 3194 return restParam(function(args) { |
| 3195 var object = args[0]; |
| 3196 if (object == null) { |
| 3197 return object; |
| 3198 } |
| 3199 args.push(customizer); |
| 3200 return assigner.apply(undefined, args); |
| 3201 }); |
| 3202 } |
| 3203 |
| 3204 /** |
| 3205 * Creates a `_.max` or `_.min` function. |
| 3206 * |
| 3207 * @private |
| 3208 * @param {Function} comparator The function used to compare values. |
| 3209 * @param {*} exValue The initial extremum value. |
| 3210 * @returns {Function} Returns the new extremum function. |
| 3211 */ |
| 3212 function createExtremum(comparator, exValue) { |
| 3213 return function(collection, iteratee, thisArg) { |
| 3214 if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
| 3215 iteratee = undefined; |
| 3216 } |
| 3217 iteratee = getCallback(iteratee, thisArg, 3); |
| 3218 if (iteratee.length == 1) { |
| 3219 collection = isArray(collection) ? collection : toIterable(collection)
; |
| 3220 var result = arrayExtremum(collection, iteratee, comparator, exValue); |
| 3221 if (!(collection.length && result === exValue)) { |
| 3222 return result; |
| 3223 } |
| 3224 } |
| 3225 return baseExtremum(collection, iteratee, comparator, exValue); |
| 3226 }; |
| 3227 } |
| 3228 |
| 3229 /** |
| 3230 * Creates a `_.find` or `_.findLast` function. |
| 3231 * |
| 3232 * @private |
| 3233 * @param {Function} eachFunc The function to iterate over a collection. |
| 3234 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 3235 * @returns {Function} Returns the new find function. |
| 3236 */ |
| 3237 function createFind(eachFunc, fromRight) { |
| 3238 return function(collection, predicate, thisArg) { |
| 3239 predicate = getCallback(predicate, thisArg, 3); |
| 3240 if (isArray(collection)) { |
| 3241 var index = baseFindIndex(collection, predicate, fromRight); |
| 3242 return index > -1 ? collection[index] : undefined; |
| 3243 } |
| 3244 return baseFind(collection, predicate, eachFunc); |
| 3245 }; |
| 3246 } |
| 3247 |
| 3248 /** |
| 3249 * Creates a `_.findIndex` or `_.findLastIndex` function. |
| 3250 * |
| 3251 * @private |
| 3252 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 3253 * @returns {Function} Returns the new find function. |
| 3254 */ |
| 3255 function createFindIndex(fromRight) { |
| 3256 return function(array, predicate, thisArg) { |
| 3257 if (!(array && array.length)) { |
| 3258 return -1; |
| 3259 } |
| 3260 predicate = getCallback(predicate, thisArg, 3); |
| 3261 return baseFindIndex(array, predicate, fromRight); |
| 3262 }; |
| 3263 } |
| 3264 |
| 3265 /** |
| 3266 * Creates a `_.findKey` or `_.findLastKey` function. |
| 3267 * |
| 3268 * @private |
| 3269 * @param {Function} objectFunc The function to iterate over an object. |
| 3270 * @returns {Function} Returns the new find function. |
| 3271 */ |
| 3272 function createFindKey(objectFunc) { |
| 3273 return function(object, predicate, thisArg) { |
| 3274 predicate = getCallback(predicate, thisArg, 3); |
| 3275 return baseFind(object, predicate, objectFunc, true); |
| 3276 }; |
| 3277 } |
| 3278 |
| 3279 /** |
| 3280 * Creates a `_.flow` or `_.flowRight` function. |
| 3281 * |
| 3282 * @private |
| 3283 * @param {boolean} [fromRight] Specify iterating from right to left. |
| 3284 * @returns {Function} Returns the new flow function. |
| 3285 */ |
| 3286 function createFlow(fromRight) { |
| 3287 return function() { |
| 3288 var wrapper, |
| 3289 length = arguments.length, |
| 3290 index = fromRight ? length : -1, |
| 3291 leftIndex = 0, |
| 3292 funcs = Array(length); |
| 3293 |
| 3294 while ((fromRight ? index-- : ++index < length)) { |
| 3295 var func = funcs[leftIndex++] = arguments[index]; |
| 3296 if (typeof func != 'function') { |
| 3297 throw new TypeError(FUNC_ERROR_TEXT); |
| 3298 } |
| 3299 if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == '
wrapper') { |
| 3300 wrapper = new LodashWrapper([], true); |
| 3301 } |
| 3302 } |
| 3303 index = wrapper ? -1 : length; |
| 3304 while (++index < length) { |
| 3305 func = funcs[index]; |
| 3306 |
| 3307 var funcName = getFuncName(func), |
| 3308 data = funcName == 'wrapper' ? getData(func) : undefined; |
| 3309 |
| 3310 if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG |
PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { |
| 3311 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); |
| 3312 } else { |
| 3313 wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]
() : wrapper.thru(func); |
| 3314 } |
| 3315 } |
| 3316 return function() { |
| 3317 var args = arguments, |
| 3318 value = args[0]; |
| 3319 |
| 3320 if (wrapper && args.length == 1 && isArray(value) && value.length >= L
ARGE_ARRAY_SIZE) { |
| 3321 return wrapper.plant(value).value(); |
| 3322 } |
| 3323 var index = 0, |
| 3324 result = length ? funcs[index].apply(this, args) : value; |
| 3325 |
| 3326 while (++index < length) { |
| 3327 result = funcs[index].call(this, result); |
| 3328 } |
| 3329 return result; |
| 3330 }; |
| 3331 }; |
| 3332 } |
| 3333 |
| 3334 /** |
| 3335 * Creates a function for `_.forEach` or `_.forEachRight`. |
| 3336 * |
| 3337 * @private |
| 3338 * @param {Function} arrayFunc The function to iterate over an array. |
| 3339 * @param {Function} eachFunc The function to iterate over a collection. |
| 3340 * @returns {Function} Returns the new each function. |
| 3341 */ |
| 3342 function createForEach(arrayFunc, eachFunc) { |
| 3343 return function(collection, iteratee, thisArg) { |
| 3344 return (typeof iteratee == 'function' && thisArg === undefined && isArra
y(collection)) |
| 3345 ? arrayFunc(collection, iteratee) |
| 3346 : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); |
| 3347 }; |
| 3348 } |
| 3349 |
| 3350 /** |
| 3351 * Creates a function for `_.forIn` or `_.forInRight`. |
| 3352 * |
| 3353 * @private |
| 3354 * @param {Function} objectFunc The function to iterate over an object. |
| 3355 * @returns {Function} Returns the new each function. |
| 3356 */ |
| 3357 function createForIn(objectFunc) { |
| 3358 return function(object, iteratee, thisArg) { |
| 3359 if (typeof iteratee != 'function' || thisArg !== undefined) { |
| 3360 iteratee = bindCallback(iteratee, thisArg, 3); |
| 3361 } |
| 3362 return objectFunc(object, iteratee, keysIn); |
| 3363 }; |
| 3364 } |
| 3365 |
| 3366 /** |
| 3367 * Creates a function for `_.forOwn` or `_.forOwnRight`. |
| 3368 * |
| 3369 * @private |
| 3370 * @param {Function} objectFunc The function to iterate over an object. |
| 3371 * @returns {Function} Returns the new each function. |
| 3372 */ |
| 3373 function createForOwn(objectFunc) { |
| 3374 return function(object, iteratee, thisArg) { |
| 3375 if (typeof iteratee != 'function' || thisArg !== undefined) { |
| 3376 iteratee = bindCallback(iteratee, thisArg, 3); |
| 3377 } |
| 3378 return objectFunc(object, iteratee); |
| 3379 }; |
| 3380 } |
| 3381 |
| 3382 /** |
| 3383 * Creates a function for `_.mapKeys` or `_.mapValues`. |
| 3384 * |
| 3385 * @private |
| 3386 * @param {boolean} [isMapKeys] Specify mapping keys instead of values. |
| 3387 * @returns {Function} Returns the new map function. |
| 3388 */ |
| 3389 function createObjectMapper(isMapKeys) { |
| 3390 return function(object, iteratee, thisArg) { |
| 3391 var result = {}; |
| 3392 iteratee = getCallback(iteratee, thisArg, 3); |
| 3393 |
| 3394 baseForOwn(object, function(value, key, object) { |
| 3395 var mapped = iteratee(value, key, object); |
| 3396 key = isMapKeys ? mapped : key; |
| 3397 value = isMapKeys ? value : mapped; |
| 3398 result[key] = value; |
| 3399 }); |
| 3400 return result; |
| 3401 }; |
| 3402 } |
| 3403 |
| 3404 /** |
| 3405 * Creates a function for `_.padLeft` or `_.padRight`. |
| 3406 * |
| 3407 * @private |
| 3408 * @param {boolean} [fromRight] Specify padding from the right. |
| 3409 * @returns {Function} Returns the new pad function. |
| 3410 */ |
| 3411 function createPadDir(fromRight) { |
| 3412 return function(string, length, chars) { |
| 3413 string = baseToString(string); |
| 3414 return (fromRight ? string : '') + createPadding(string, length, chars)
+ (fromRight ? '' : string); |
| 3415 }; |
| 3416 } |
| 3417 |
| 3418 /** |
| 3419 * Creates a `_.partial` or `_.partialRight` function. |
| 3420 * |
| 3421 * @private |
| 3422 * @param {boolean} flag The partial bit flag. |
| 3423 * @returns {Function} Returns the new partial function. |
| 3424 */ |
| 3425 function createPartial(flag) { |
| 3426 var partialFunc = restParam(function(func, partials) { |
| 3427 var holders = replaceHolders(partials, partialFunc.placeholder); |
| 3428 return createWrapper(func, flag, undefined, partials, holders); |
| 3429 }); |
| 3430 return partialFunc; |
| 3431 } |
| 3432 |
| 3433 /** |
| 3434 * Creates a function for `_.reduce` or `_.reduceRight`. |
| 3435 * |
| 3436 * @private |
| 3437 * @param {Function} arrayFunc The function to iterate over an array. |
| 3438 * @param {Function} eachFunc The function to iterate over a collection. |
| 3439 * @returns {Function} Returns the new each function. |
| 3440 */ |
| 3441 function createReduce(arrayFunc, eachFunc) { |
| 3442 return function(collection, iteratee, accumulator, thisArg) { |
| 3443 var initFromArray = arguments.length < 3; |
| 3444 return (typeof iteratee == 'function' && thisArg === undefined && isArra
y(collection)) |
| 3445 ? arrayFunc(collection, iteratee, accumulator, initFromArray) |
| 3446 : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulato
r, initFromArray, eachFunc); |
| 3447 }; |
| 3448 } |
| 3449 |
| 3450 /** |
| 3451 * Creates a function that wraps `func` and invokes it with optional `this` |
| 3452 * binding of, partial application, and currying. |
| 3453 * |
| 3454 * @private |
| 3455 * @param {Function|string} func The function or method name to reference. |
| 3456 * @param {number} bitmask The bitmask of flags. See `createWrapper` for mor
e details. |
| 3457 * @param {*} [thisArg] The `this` binding of `func`. |
| 3458 * @param {Array} [partials] The arguments to prepend to those provided to t
he new function. |
| 3459 * @param {Array} [holders] The `partials` placeholder indexes. |
| 3460 * @param {Array} [partialsRight] The arguments to append to those provided
to the new function. |
| 3461 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. |
| 3462 * @param {Array} [argPos] The argument positions of the new function. |
| 3463 * @param {number} [ary] The arity cap of `func`. |
| 3464 * @param {number} [arity] The arity of `func`. |
| 3465 * @returns {Function} Returns the new wrapped function. |
| 3466 */ |
| 3467 function createHybridWrapper(func, bitmask, thisArg, partials, holders, part
ialsRight, holdersRight, argPos, ary, arity) { |
| 3468 var isAry = bitmask & ARY_FLAG, |
| 3469 isBind = bitmask & BIND_FLAG, |
| 3470 isBindKey = bitmask & BIND_KEY_FLAG, |
| 3471 isCurry = bitmask & CURRY_FLAG, |
| 3472 isCurryBound = bitmask & CURRY_BOUND_FLAG, |
| 3473 isCurryRight = bitmask & CURRY_RIGHT_FLAG, |
| 3474 Ctor = isBindKey ? undefined : createCtorWrapper(func); |
| 3475 |
| 3476 function wrapper() { |
| 3477 // Avoid `arguments` object use disqualifying optimizations by |
| 3478 // converting it to an array before providing it to other functions. |
| 3479 var length = arguments.length, |
| 3480 index = length, |
| 3481 args = Array(length); |
| 3482 |
| 3483 while (index--) { |
| 3484 args[index] = arguments[index]; |
| 3485 } |
| 3486 if (partials) { |
| 3487 args = composeArgs(args, partials, holders); |
| 3488 } |
| 3489 if (partialsRight) { |
| 3490 args = composeArgsRight(args, partialsRight, holdersRight); |
| 3491 } |
| 3492 if (isCurry || isCurryRight) { |
| 3493 var placeholder = wrapper.placeholder, |
| 3494 argsHolders = replaceHolders(args, placeholder); |
| 3495 |
| 3496 length -= argsHolders.length; |
| 3497 if (length < arity) { |
| 3498 var newArgPos = argPos ? arrayCopy(argPos) : undefined, |
| 3499 newArity = nativeMax(arity - length, 0), |
| 3500 newsHolders = isCurry ? argsHolders : undefined, |
| 3501 newHoldersRight = isCurry ? undefined : argsHolders, |
| 3502 newPartials = isCurry ? args : undefined, |
| 3503 newPartialsRight = isCurry ? undefined : args; |
| 3504 |
| 3505 bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); |
| 3506 bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); |
| 3507 |
| 3508 if (!isCurryBound) { |
| 3509 bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); |
| 3510 } |
| 3511 var newData = [func, bitmask, thisArg, newPartials, newsHolders, new
PartialsRight, newHoldersRight, newArgPos, ary, newArity], |
| 3512 result = createHybridWrapper.apply(undefined, newData); |
| 3513 |
| 3514 if (isLaziable(func)) { |
| 3515 setData(result, newData); |
| 3516 } |
| 3517 result.placeholder = placeholder; |
| 3518 return result; |
| 3519 } |
| 3520 } |
| 3521 var thisBinding = isBind ? thisArg : this, |
| 3522 fn = isBindKey ? thisBinding[func] : func; |
| 3523 |
| 3524 if (argPos) { |
| 3525 args = reorder(args, argPos); |
| 3526 } |
| 3527 if (isAry && ary < args.length) { |
| 3528 args.length = ary; |
| 3529 } |
| 3530 if (this && this !== root && this instanceof wrapper) { |
| 3531 fn = Ctor || createCtorWrapper(func); |
| 3532 } |
| 3533 return fn.apply(thisBinding, args); |
| 3534 } |
| 3535 return wrapper; |
| 3536 } |
| 3537 |
| 3538 /** |
| 3539 * Creates the padding required for `string` based on the given `length`. |
| 3540 * The `chars` string is truncated if the number of characters exceeds `leng
th`. |
| 3541 * |
| 3542 * @private |
| 3543 * @param {string} string The string to create padding for. |
| 3544 * @param {number} [length=0] The padding length. |
| 3545 * @param {string} [chars=' '] The string used as padding. |
| 3546 * @returns {string} Returns the pad for `string`. |
| 3547 */ |
| 3548 function createPadding(string, length, chars) { |
| 3549 var strLength = string.length; |
| 3550 length = +length; |
| 3551 |
| 3552 if (strLength >= length || !nativeIsFinite(length)) { |
| 3553 return ''; |
| 3554 } |
| 3555 var padLength = length - strLength; |
| 3556 chars = chars == null ? ' ' : (chars + ''); |
| 3557 return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLen
gth); |
| 3558 } |
| 3559 |
| 3560 /** |
| 3561 * Creates a function that wraps `func` and invokes it with the optional `th
is` |
| 3562 * binding of `thisArg` and the `partials` prepended to those provided to |
| 3563 * the wrapper. |
| 3564 * |
| 3565 * @private |
| 3566 * @param {Function} func The function to partially apply arguments to. |
| 3567 * @param {number} bitmask The bitmask of flags. See `createWrapper` for mor
e details. |
| 3568 * @param {*} thisArg The `this` binding of `func`. |
| 3569 * @param {Array} partials The arguments to prepend to those provided to the
new function. |
| 3570 * @returns {Function} Returns the new bound function. |
| 3571 */ |
| 3572 function createPartialWrapper(func, bitmask, thisArg, partials) { |
| 3573 var isBind = bitmask & BIND_FLAG, |
| 3574 Ctor = createCtorWrapper(func); |
| 3575 |
| 3576 function wrapper() { |
| 3577 // Avoid `arguments` object use disqualifying optimizations by |
| 3578 // converting it to an array before providing it `func`. |
| 3579 var argsIndex = -1, |
| 3580 argsLength = arguments.length, |
| 3581 leftIndex = -1, |
| 3582 leftLength = partials.length, |
| 3583 args = Array(leftLength + argsLength); |
| 3584 |
| 3585 while (++leftIndex < leftLength) { |
| 3586 args[leftIndex] = partials[leftIndex]; |
| 3587 } |
| 3588 while (argsLength--) { |
| 3589 args[leftIndex++] = arguments[++argsIndex]; |
| 3590 } |
| 3591 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : fun
c; |
| 3592 return fn.apply(isBind ? thisArg : this, args); |
| 3593 } |
| 3594 return wrapper; |
| 3595 } |
| 3596 |
| 3597 /** |
| 3598 * Creates a `_.ceil`, `_.floor`, or `_.round` function. |
| 3599 * |
| 3600 * @private |
| 3601 * @param {string} methodName The name of the `Math` method to use when roun
ding. |
| 3602 * @returns {Function} Returns the new round function. |
| 3603 */ |
| 3604 function createRound(methodName) { |
| 3605 var func = Math[methodName]; |
| 3606 return function(number, precision) { |
| 3607 precision = precision === undefined ? 0 : (+precision || 0); |
| 3608 if (precision) { |
| 3609 precision = pow(10, precision); |
| 3610 return func(number * precision) / precision; |
| 3611 } |
| 3612 return func(number); |
| 3613 }; |
| 3614 } |
| 3615 |
| 3616 /** |
| 3617 * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. |
| 3618 * |
| 3619 * @private |
| 3620 * @param {boolean} [retHighest] Specify returning the highest qualified ind
ex. |
| 3621 * @returns {Function} Returns the new index function. |
| 3622 */ |
| 3623 function createSortedIndex(retHighest) { |
| 3624 return function(array, value, iteratee, thisArg) { |
| 3625 var callback = getCallback(iteratee); |
| 3626 return (iteratee == null && callback === baseCallback) |
| 3627 ? binaryIndex(array, value, retHighest) |
| 3628 : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighe
st); |
| 3629 }; |
| 3630 } |
| 3631 |
| 3632 /** |
| 3633 * Creates a function that either curries or invokes `func` with optional |
| 3634 * `this` binding and partially applied arguments. |
| 3635 * |
| 3636 * @private |
| 3637 * @param {Function|string} func The function or method name to reference. |
| 3638 * @param {number} bitmask The bitmask of flags. |
| 3639 * The bitmask may be composed of the following flags: |
| 3640 * 1 - `_.bind` |
| 3641 * 2 - `_.bindKey` |
| 3642 * 4 - `_.curry` or `_.curryRight` of a bound function |
| 3643 * 8 - `_.curry` |
| 3644 * 16 - `_.curryRight` |
| 3645 * 32 - `_.partial` |
| 3646 * 64 - `_.partialRight` |
| 3647 * 128 - `_.rearg` |
| 3648 * 256 - `_.ary` |
| 3649 * @param {*} [thisArg] The `this` binding of `func`. |
| 3650 * @param {Array} [partials] The arguments to be partially applied. |
| 3651 * @param {Array} [holders] The `partials` placeholder indexes. |
| 3652 * @param {Array} [argPos] The argument positions of the new function. |
| 3653 * @param {number} [ary] The arity cap of `func`. |
| 3654 * @param {number} [arity] The arity of `func`. |
| 3655 * @returns {Function} Returns the new wrapped function. |
| 3656 */ |
| 3657 function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ar
y, arity) { |
| 3658 var isBindKey = bitmask & BIND_KEY_FLAG; |
| 3659 if (!isBindKey && typeof func != 'function') { |
| 3660 throw new TypeError(FUNC_ERROR_TEXT); |
| 3661 } |
| 3662 var length = partials ? partials.length : 0; |
| 3663 if (!length) { |
| 3664 bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); |
| 3665 partials = holders = undefined; |
| 3666 } |
| 3667 length -= (holders ? holders.length : 0); |
| 3668 if (bitmask & PARTIAL_RIGHT_FLAG) { |
| 3669 var partialsRight = partials, |
| 3670 holdersRight = holders; |
| 3671 |
| 3672 partials = holders = undefined; |
| 3673 } |
| 3674 var data = isBindKey ? undefined : getData(func), |
| 3675 newData = [func, bitmask, thisArg, partials, holders, partialsRight, h
oldersRight, argPos, ary, arity]; |
| 3676 |
| 3677 if (data) { |
| 3678 mergeData(newData, data); |
| 3679 bitmask = newData[1]; |
| 3680 arity = newData[9]; |
| 3681 } |
| 3682 newData[9] = arity == null |
| 3683 ? (isBindKey ? 0 : func.length) |
| 3684 : (nativeMax(arity - length, 0) || 0); |
| 3685 |
| 3686 if (bitmask == BIND_FLAG) { |
| 3687 var result = createBindWrapper(newData[0], newData[2]); |
| 3688 } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLA
G)) && !newData[4].length) { |
| 3689 result = createPartialWrapper.apply(undefined, newData); |
| 3690 } else { |
| 3691 result = createHybridWrapper.apply(undefined, newData); |
| 3692 } |
| 3693 var setter = data ? baseSetData : setData; |
| 3694 return setter(result, newData); |
| 3695 } |
| 3696 |
| 3697 /** |
| 3698 * A specialized version of `baseIsEqualDeep` for arrays with support for |
| 3699 * partial deep comparisons. |
| 3700 * |
| 3701 * @private |
| 3702 * @param {Array} array The array to compare. |
| 3703 * @param {Array} other The other array to compare. |
| 3704 * @param {Function} equalFunc The function to determine equivalents of valu
es. |
| 3705 * @param {Function} [customizer] The function to customize comparing arrays
. |
| 3706 * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 3707 * @param {Array} [stackA] Tracks traversed `value` objects. |
| 3708 * @param {Array} [stackB] Tracks traversed `other` objects. |
| 3709 * @returns {boolean} Returns `true` if the arrays are equivalent, else `fal
se`. |
| 3710 */ |
| 3711 function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, s
tackB) { |
| 3712 var index = -1, |
| 3713 arrLength = array.length, |
| 3714 othLength = other.length; |
| 3715 |
| 3716 if (arrLength != othLength && !(isLoose && othLength > arrLength)) { |
| 3717 return false; |
| 3718 } |
| 3719 // Ignore non-index properties. |
| 3720 while (++index < arrLength) { |
| 3721 var arrValue = array[index], |
| 3722 othValue = other[index], |
| 3723 result = customizer ? customizer(isLoose ? othValue : arrValue, isLo
ose ? arrValue : othValue, index) : undefined; |
| 3724 |
| 3725 if (result !== undefined) { |
| 3726 if (result) { |
| 3727 continue; |
| 3728 } |
| 3729 return false; |
| 3730 } |
| 3731 // Recursively compare arrays (susceptible to call stack limits). |
| 3732 if (isLoose) { |
| 3733 if (!arraySome(other, function(othValue) { |
| 3734 return arrValue === othValue || equalFunc(arrValue, othValue, cu
stomizer, isLoose, stackA, stackB); |
| 3735 })) { |
| 3736 return false; |
| 3737 } |
| 3738 } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, cust
omizer, isLoose, stackA, stackB))) { |
| 3739 return false; |
| 3740 } |
| 3741 } |
| 3742 return true; |
| 3743 } |
| 3744 |
| 3745 /** |
| 3746 * A specialized version of `baseIsEqualDeep` for comparing objects of |
| 3747 * the same `toStringTag`. |
| 3748 * |
| 3749 * **Note:** This function only supports comparing values with tags of |
| 3750 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| 3751 * |
| 3752 * @private |
| 3753 * @param {Object} object The object to compare. |
| 3754 * @param {Object} other The other object to compare. |
| 3755 * @param {string} tag The `toStringTag` of the objects to compare. |
| 3756 * @returns {boolean} Returns `true` if the objects are equivalent, else `fa
lse`. |
| 3757 */ |
| 3758 function equalByTag(object, other, tag) { |
| 3759 switch (tag) { |
| 3760 case boolTag: |
| 3761 case dateTag: |
| 3762 // Coerce dates and booleans to numbers, dates to milliseconds and boo
leans |
| 3763 // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. |
| 3764 return +object == +other; |
| 3765 |
| 3766 case errorTag: |
| 3767 return object.name == other.name && object.message == other.message; |
| 3768 |
| 3769 case numberTag: |
| 3770 // Treat `NaN` vs. `NaN` as equal. |
| 3771 return (object != +object) |
| 3772 ? other != +other |
| 3773 : object == +other; |
| 3774 |
| 3775 case regexpTag: |
| 3776 case stringTag: |
| 3777 // Coerce regexes to strings and treat strings primitives and string |
| 3778 // objects as equal. See https://es5.github.io/#x15.10.6.4 for more de
tails. |
| 3779 return object == (other + ''); |
| 3780 } |
| 3781 return false; |
| 3782 } |
| 3783 |
| 3784 /** |
| 3785 * A specialized version of `baseIsEqualDeep` for objects with support for |
| 3786 * partial deep comparisons. |
| 3787 * |
| 3788 * @private |
| 3789 * @param {Object} object The object to compare. |
| 3790 * @param {Object} other The other object to compare. |
| 3791 * @param {Function} equalFunc The function to determine equivalents of valu
es. |
| 3792 * @param {Function} [customizer] The function to customize comparing values
. |
| 3793 * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 3794 * @param {Array} [stackA] Tracks traversed `value` objects. |
| 3795 * @param {Array} [stackB] Tracks traversed `other` objects. |
| 3796 * @returns {boolean} Returns `true` if the objects are equivalent, else `fa
lse`. |
| 3797 */ |
| 3798 function equalObjects(object, other, equalFunc, customizer, isLoose, stackA,
stackB) { |
| 3799 var objProps = keys(object), |
| 3800 objLength = objProps.length, |
| 3801 othProps = keys(other), |
| 3802 othLength = othProps.length; |
| 3803 |
| 3804 if (objLength != othLength && !isLoose) { |
| 3805 return false; |
| 3806 } |
| 3807 var index = objLength; |
| 3808 while (index--) { |
| 3809 var key = objProps[index]; |
| 3810 if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { |
| 3811 return false; |
| 3812 } |
| 3813 } |
| 3814 var skipCtor = isLoose; |
| 3815 while (++index < objLength) { |
| 3816 key = objProps[index]; |
| 3817 var objValue = object[key], |
| 3818 othValue = other[key], |
| 3819 result = customizer ? customizer(isLoose ? othValue : objValue, isLo
ose? objValue : othValue, key) : undefined; |
| 3820 |
| 3821 // Recursively compare objects (susceptible to call stack limits). |
| 3822 if (!(result === undefined ? equalFunc(objValue, othValue, customizer, i
sLoose, stackA, stackB) : result)) { |
| 3823 return false; |
| 3824 } |
| 3825 skipCtor || (skipCtor = key == 'constructor'); |
| 3826 } |
| 3827 if (!skipCtor) { |
| 3828 var objCtor = object.constructor, |
| 3829 othCtor = other.constructor; |
| 3830 |
| 3831 // Non `Object` object instances with different constructors are not equ
al. |
| 3832 if (objCtor != othCtor && |
| 3833 ('constructor' in object && 'constructor' in other) && |
| 3834 !(typeof objCtor == 'function' && objCtor instanceof objCtor && |
| 3835 typeof othCtor == 'function' && othCtor instanceof othCtor)) { |
| 3836 return false; |
| 3837 } |
| 3838 } |
| 3839 return true; |
| 3840 } |
| 3841 |
| 3842 /** |
| 3843 * Gets the appropriate "callback" function. If the `_.callback` method is |
| 3844 * customized this function returns the custom method, otherwise it returns |
| 3845 * the `baseCallback` function. If arguments are provided the chosen functio
n |
| 3846 * is invoked with them and its result is returned. |
| 3847 * |
| 3848 * @private |
| 3849 * @returns {Function} Returns the chosen function or its result. |
| 3850 */ |
| 3851 function getCallback(func, thisArg, argCount) { |
| 3852 var result = lodash.callback || callback; |
| 3853 result = result === callback ? baseCallback : result; |
| 3854 return argCount ? result(func, thisArg, argCount) : result; |
| 3855 } |
| 3856 |
| 3857 /** |
| 3858 * Gets metadata for `func`. |
| 3859 * |
| 3860 * @private |
| 3861 * @param {Function} func The function to query. |
| 3862 * @returns {*} Returns the metadata for `func`. |
| 3863 */ |
| 3864 var getData = !metaMap ? noop : function(func) { |
| 3865 return metaMap.get(func); |
| 3866 }; |
| 3867 |
| 3868 /** |
| 3869 * Gets the name of `func`. |
| 3870 * |
| 3871 * @private |
| 3872 * @param {Function} func The function to query. |
| 3873 * @returns {string} Returns the function name. |
| 3874 */ |
| 3875 function getFuncName(func) { |
| 3876 var result = (func.name + ''), |
| 3877 array = realNames[result], |
| 3878 length = array ? array.length : 0; |
| 3879 |
| 3880 while (length--) { |
| 3881 var data = array[length], |
| 3882 otherFunc = data.func; |
| 3883 if (otherFunc == null || otherFunc == func) { |
| 3884 return data.name; |
| 3885 } |
| 3886 } |
| 3887 return result; |
| 3888 } |
| 3889 |
| 3890 /** |
| 3891 * Gets the appropriate "indexOf" function. If the `_.indexOf` method is |
| 3892 * customized this function returns the custom method, otherwise it returns |
| 3893 * the `baseIndexOf` function. If arguments are provided the chosen function |
| 3894 * is invoked with them and its result is returned. |
| 3895 * |
| 3896 * @private |
| 3897 * @returns {Function|number} Returns the chosen function or its result. |
| 3898 */ |
| 3899 function getIndexOf(collection, target, fromIndex) { |
| 3900 var result = lodash.indexOf || indexOf; |
| 3901 result = result === indexOf ? baseIndexOf : result; |
| 3902 return collection ? result(collection, target, fromIndex) : result; |
| 3903 } |
| 3904 |
| 3905 /** |
| 3906 * Gets the "length" property value of `object`. |
| 3907 * |
| 3908 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.
org/show_bug.cgi?id=142792) |
| 3909 * that affects Safari on at least iOS 8.1-8.3 ARM64. |
| 3910 * |
| 3911 * @private |
| 3912 * @param {Object} object The object to query. |
| 3913 * @returns {*} Returns the "length" value. |
| 3914 */ |
| 3915 var getLength = baseProperty('length'); |
| 3916 |
| 3917 /** |
| 3918 * Gets the propery names, values, and compare flags of `object`. |
| 3919 * |
| 3920 * @private |
| 3921 * @param {Object} object The object to query. |
| 3922 * @returns {Array} Returns the match data of `object`. |
| 3923 */ |
| 3924 function getMatchData(object) { |
| 3925 var result = pairs(object), |
| 3926 length = result.length; |
| 3927 |
| 3928 while (length--) { |
| 3929 result[length][2] = isStrictComparable(result[length][1]); |
| 3930 } |
| 3931 return result; |
| 3932 } |
| 3933 |
| 3934 /** |
| 3935 * Gets the native function at `key` of `object`. |
| 3936 * |
| 3937 * @private |
| 3938 * @param {Object} object The object to query. |
| 3939 * @param {string} key The key of the method to get. |
| 3940 * @returns {*} Returns the function if it's native, else `undefined`. |
| 3941 */ |
| 3942 function getNative(object, key) { |
| 3943 var value = object == null ? undefined : object[key]; |
| 3944 return isNative(value) ? value : undefined; |
| 3945 } |
| 3946 |
| 3947 /** |
| 3948 * Gets the view, applying any `transforms` to the `start` and `end` positio
ns. |
| 3949 * |
| 3950 * @private |
| 3951 * @param {number} start The start of the view. |
| 3952 * @param {number} end The end of the view. |
| 3953 * @param {Array} transforms The transformations to apply to the view. |
| 3954 * @returns {Object} Returns an object containing the `start` and `end` |
| 3955 * positions of the view. |
| 3956 */ |
| 3957 function getView(start, end, transforms) { |
| 3958 var index = -1, |
| 3959 length = transforms.length; |
| 3960 |
| 3961 while (++index < length) { |
| 3962 var data = transforms[index], |
| 3963 size = data.size; |
| 3964 |
| 3965 switch (data.type) { |
| 3966 case 'drop': start += size; break; |
| 3967 case 'dropRight': end -= size; break; |
| 3968 case 'take': end = nativeMin(end, start + size); break; |
| 3969 case 'takeRight': start = nativeMax(start, end - size); break; |
| 3970 } |
| 3971 } |
| 3972 return { 'start': start, 'end': end }; |
| 3973 } |
| 3974 |
| 3975 /** |
| 3976 * Initializes an array clone. |
| 3977 * |
| 3978 * @private |
| 3979 * @param {Array} array The array to clone. |
| 3980 * @returns {Array} Returns the initialized clone. |
| 3981 */ |
| 3982 function initCloneArray(array) { |
| 3983 var length = array.length, |
| 3984 result = new array.constructor(length); |
| 3985 |
| 3986 // Add array properties assigned by `RegExp#exec`. |
| 3987 if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'i
ndex')) { |
| 3988 result.index = array.index; |
| 3989 result.input = array.input; |
| 3990 } |
| 3991 return result; |
| 3992 } |
| 3993 |
| 3994 /** |
| 3995 * Initializes an object clone. |
| 3996 * |
| 3997 * @private |
| 3998 * @param {Object} object The object to clone. |
| 3999 * @returns {Object} Returns the initialized clone. |
| 4000 */ |
| 4001 function initCloneObject(object) { |
| 4002 var Ctor = object.constructor; |
| 4003 if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { |
| 4004 Ctor = Object; |
| 4005 } |
| 4006 return new Ctor; |
| 4007 } |
| 4008 |
| 4009 /** |
| 4010 * Initializes an object clone based on its `toStringTag`. |
| 4011 * |
| 4012 * **Note:** This function only supports cloning values with tags of |
| 4013 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| 4014 * |
| 4015 * @private |
| 4016 * @param {Object} object The object to clone. |
| 4017 * @param {string} tag The `toStringTag` of the object to clone. |
| 4018 * @param {boolean} [isDeep] Specify a deep clone. |
| 4019 * @returns {Object} Returns the initialized clone. |
| 4020 */ |
| 4021 function initCloneByTag(object, tag, isDeep) { |
| 4022 var Ctor = object.constructor; |
| 4023 switch (tag) { |
| 4024 case arrayBufferTag: |
| 4025 return bufferClone(object); |
| 4026 |
| 4027 case boolTag: |
| 4028 case dateTag: |
| 4029 return new Ctor(+object); |
| 4030 |
| 4031 case float32Tag: case float64Tag: |
| 4032 case int8Tag: case int16Tag: case int32Tag: |
| 4033 case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: |
| 4034 var buffer = object.buffer; |
| 4035 return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffs
et, object.length); |
| 4036 |
| 4037 case numberTag: |
| 4038 case stringTag: |
| 4039 return new Ctor(object); |
| 4040 |
| 4041 case regexpTag: |
| 4042 var result = new Ctor(object.source, reFlags.exec(object)); |
| 4043 result.lastIndex = object.lastIndex; |
| 4044 } |
| 4045 return result; |
| 4046 } |
| 4047 |
| 4048 /** |
| 4049 * Invokes the method at `path` on `object`. |
| 4050 * |
| 4051 * @private |
| 4052 * @param {Object} object The object to query. |
| 4053 * @param {Array|string} path The path of the method to invoke. |
| 4054 * @param {Array} args The arguments to invoke the method with. |
| 4055 * @returns {*} Returns the result of the invoked method. |
| 4056 */ |
| 4057 function invokePath(object, path, args) { |
| 4058 if (object != null && !isKey(path, object)) { |
| 4059 path = toPath(path); |
| 4060 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0,
-1)); |
| 4061 path = last(path); |
| 4062 } |
| 4063 var func = object == null ? object : object[path]; |
| 4064 return func == null ? undefined : func.apply(object, args); |
| 4065 } |
| 4066 |
| 4067 /** |
| 4068 * Checks if `value` is array-like. |
| 4069 * |
| 4070 * @private |
| 4071 * @param {*} value The value to check. |
| 4072 * @returns {boolean} Returns `true` if `value` is array-like, else `false`. |
| 4073 */ |
| 4074 function isArrayLike(value) { |
| 4075 return value != null && isLength(getLength(value)); |
| 4076 } |
| 4077 |
| 4078 /** |
| 4079 * Checks if `value` is a valid array-like index. |
| 4080 * |
| 4081 * @private |
| 4082 * @param {*} value The value to check. |
| 4083 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid ind
ex. |
| 4084 * @returns {boolean} Returns `true` if `value` is a valid index, else `fals
e`. |
| 4085 */ |
| 4086 function isIndex(value, length) { |
| 4087 value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; |
| 4088 length = length == null ? MAX_SAFE_INTEGER : length; |
| 4089 return value > -1 && value % 1 == 0 && value < length; |
| 4090 } |
| 4091 |
| 4092 /** |
| 4093 * Checks if the provided arguments are from an iteratee call. |
| 4094 * |
| 4095 * @private |
| 4096 * @param {*} value The potential iteratee value argument. |
| 4097 * @param {*} index The potential iteratee index or key argument. |
| 4098 * @param {*} object The potential iteratee object argument. |
| 4099 * @returns {boolean} Returns `true` if the arguments are from an iteratee c
all, else `false`. |
| 4100 */ |
| 4101 function isIterateeCall(value, index, object) { |
| 4102 if (!isObject(object)) { |
| 4103 return false; |
| 4104 } |
| 4105 var type = typeof index; |
| 4106 if (type == 'number' |
| 4107 ? (isArrayLike(object) && isIndex(index, object.length)) |
| 4108 : (type == 'string' && index in object)) { |
| 4109 var other = object[index]; |
| 4110 return value === value ? (value === other) : (other !== other); |
| 4111 } |
| 4112 return false; |
| 4113 } |
| 4114 |
| 4115 /** |
| 4116 * Checks if `value` is a property name and not a property path. |
| 4117 * |
| 4118 * @private |
| 4119 * @param {*} value The value to check. |
| 4120 * @param {Object} [object] The object to query keys on. |
| 4121 * @returns {boolean} Returns `true` if `value` is a property name, else `fa
lse`. |
| 4122 */ |
| 4123 function isKey(value, object) { |
| 4124 var type = typeof value; |
| 4125 if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { |
| 4126 return true; |
| 4127 } |
| 4128 if (isArray(value)) { |
| 4129 return false; |
| 4130 } |
| 4131 var result = !reIsDeepProp.test(value); |
| 4132 return result || (object != null && value in toObject(object)); |
| 4133 } |
| 4134 |
| 4135 /** |
| 4136 * Checks if `func` has a lazy counterpart. |
| 4137 * |
| 4138 * @private |
| 4139 * @param {Function} func The function to check. |
| 4140 * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else
`false`. |
| 4141 */ |
| 4142 function isLaziable(func) { |
| 4143 var funcName = getFuncName(func), |
| 4144 other = lodash[funcName]; |
| 4145 |
| 4146 if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { |
| 4147 return false; |
| 4148 } |
| 4149 if (func === other) { |
| 4150 return true; |
| 4151 } |
| 4152 var data = getData(other); |
| 4153 return !!data && func === data[0]; |
| 4154 } |
| 4155 |
| 4156 /** |
| 4157 * Checks if `value` is a valid array-like length. |
| 4158 * |
| 4159 * **Note:** This function is based on [`ToLength`](http://ecma-internationa
l.org/ecma-262/6.0/#sec-tolength). |
| 4160 * |
| 4161 * @private |
| 4162 * @param {*} value The value to check. |
| 4163 * @returns {boolean} Returns `true` if `value` is a valid length, else `fal
se`. |
| 4164 */ |
| 4165 function isLength(value) { |
| 4166 return typeof value == 'number' && value > -1 && value % 1 == 0 && value <
= MAX_SAFE_INTEGER; |
| 4167 } |
| 4168 |
| 4169 /** |
| 4170 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`
. |
| 4171 * |
| 4172 * @private |
| 4173 * @param {*} value The value to check. |
| 4174 * @returns {boolean} Returns `true` if `value` if suitable for strict |
| 4175 * equality comparisons, else `false`. |
| 4176 */ |
| 4177 function isStrictComparable(value) { |
| 4178 return value === value && !isObject(value); |
| 4179 } |
| 4180 |
| 4181 /** |
| 4182 * Merges the function metadata of `source` into `data`. |
| 4183 * |
| 4184 * Merging metadata reduces the number of wrappers required to invoke a func
tion. |
| 4185 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial
` |
| 4186 * may be applied regardless of execution order. Methods like `_.ary` and `_
.rearg` |
| 4187 * augment function arguments, making the order in which they are executed i
mportant, |
| 4188 * preventing the merging of metadata. However, we make an exception for a s
afe |
| 4189 * common case where curried functions have `_.ary` and or `_.rearg` applied
. |
| 4190 * |
| 4191 * @private |
| 4192 * @param {Array} data The destination metadata. |
| 4193 * @param {Array} source The source metadata. |
| 4194 * @returns {Array} Returns `data`. |
| 4195 */ |
| 4196 function mergeData(data, source) { |
| 4197 var bitmask = data[1], |
| 4198 srcBitmask = source[1], |
| 4199 newBitmask = bitmask | srcBitmask, |
| 4200 isCommon = newBitmask < ARY_FLAG; |
| 4201 |
| 4202 var isCombo = |
| 4203 (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || |
| 4204 (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= so
urce[8]) || |
| 4205 (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); |
| 4206 |
| 4207 // Exit early if metadata can't be merged. |
| 4208 if (!(isCommon || isCombo)) { |
| 4209 return data; |
| 4210 } |
| 4211 // Use source `thisArg` if available. |
| 4212 if (srcBitmask & BIND_FLAG) { |
| 4213 data[2] = source[2]; |
| 4214 // Set when currying a bound function. |
| 4215 newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; |
| 4216 } |
| 4217 // Compose partial arguments. |
| 4218 var value = source[3]; |
| 4219 if (value) { |
| 4220 var partials = data[3]; |
| 4221 data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy
(value); |
| 4222 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(so
urce[4]); |
| 4223 } |
| 4224 // Compose partial right arguments. |
| 4225 value = source[5]; |
| 4226 if (value) { |
| 4227 partials = data[5]; |
| 4228 data[5] = partials ? composeArgsRight(partials, value, source[6]) : arra
yCopy(value); |
| 4229 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(so
urce[6]); |
| 4230 } |
| 4231 // Use source `argPos` if available. |
| 4232 value = source[7]; |
| 4233 if (value) { |
| 4234 data[7] = arrayCopy(value); |
| 4235 } |
| 4236 // Use source `ary` if it's smaller. |
| 4237 if (srcBitmask & ARY_FLAG) { |
| 4238 data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); |
| 4239 } |
| 4240 // Use source `arity` if one is not provided. |
| 4241 if (data[9] == null) { |
| 4242 data[9] = source[9]; |
| 4243 } |
| 4244 // Use source `func` and merge bitmasks. |
| 4245 data[0] = source[0]; |
| 4246 data[1] = newBitmask; |
| 4247 |
| 4248 return data; |
| 4249 } |
| 4250 |
| 4251 /** |
| 4252 * Used by `_.defaultsDeep` to customize its `_.merge` use. |
| 4253 * |
| 4254 * @private |
| 4255 * @param {*} objectValue The destination object property value. |
| 4256 * @param {*} sourceValue The source object property value. |
| 4257 * @returns {*} Returns the value to assign to the destination object. |
| 4258 */ |
| 4259 function mergeDefaults(objectValue, sourceValue) { |
| 4260 return objectValue === undefined ? sourceValue : merge(objectValue, source
Value, mergeDefaults); |
| 4261 } |
| 4262 |
| 4263 /** |
| 4264 * A specialized version of `_.pick` which picks `object` properties specifi
ed |
| 4265 * by `props`. |
| 4266 * |
| 4267 * @private |
| 4268 * @param {Object} object The source object. |
| 4269 * @param {string[]} props The property names to pick. |
| 4270 * @returns {Object} Returns the new object. |
| 4271 */ |
| 4272 function pickByArray(object, props) { |
| 4273 object = toObject(object); |
| 4274 |
| 4275 var index = -1, |
| 4276 length = props.length, |
| 4277 result = {}; |
| 4278 |
| 4279 while (++index < length) { |
| 4280 var key = props[index]; |
| 4281 if (key in object) { |
| 4282 result[key] = object[key]; |
| 4283 } |
| 4284 } |
| 4285 return result; |
| 4286 } |
| 4287 |
| 4288 /** |
| 4289 * A specialized version of `_.pick` which picks `object` properties `predic
ate` |
| 4290 * returns truthy for. |
| 4291 * |
| 4292 * @private |
| 4293 * @param {Object} object The source object. |
| 4294 * @param {Function} predicate The function invoked per iteration. |
| 4295 * @returns {Object} Returns the new object. |
| 4296 */ |
| 4297 function pickByCallback(object, predicate) { |
| 4298 var result = {}; |
| 4299 baseForIn(object, function(value, key, object) { |
| 4300 if (predicate(value, key, object)) { |
| 4301 result[key] = value; |
| 4302 } |
| 4303 }); |
| 4304 return result; |
| 4305 } |
| 4306 |
| 4307 /** |
| 4308 * Reorder `array` according to the specified indexes where the element at |
| 4309 * the first index is assigned as the first element, the element at |
| 4310 * the second index is assigned as the second element, and so on. |
| 4311 * |
| 4312 * @private |
| 4313 * @param {Array} array The array to reorder. |
| 4314 * @param {Array} indexes The arranged array indexes. |
| 4315 * @returns {Array} Returns `array`. |
| 4316 */ |
| 4317 function reorder(array, indexes) { |
| 4318 var arrLength = array.length, |
| 4319 length = nativeMin(indexes.length, arrLength), |
| 4320 oldArray = arrayCopy(array); |
| 4321 |
| 4322 while (length--) { |
| 4323 var index = indexes[length]; |
| 4324 array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; |
| 4325 } |
| 4326 return array; |
| 4327 } |
| 4328 |
| 4329 /** |
| 4330 * Sets metadata for `func`. |
| 4331 * |
| 4332 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short |
| 4333 * period of time, it will trip its breaker and transition to an identity fu
nction |
| 4334 * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://cod
e.google.com/p/v8/issues/detail?id=2070) |
| 4335 * for more details. |
| 4336 * |
| 4337 * @private |
| 4338 * @param {Function} func The function to associate metadata with. |
| 4339 * @param {*} data The metadata. |
| 4340 * @returns {Function} Returns `func`. |
| 4341 */ |
| 4342 var setData = (function() { |
| 4343 var count = 0, |
| 4344 lastCalled = 0; |
| 4345 |
| 4346 return function(key, value) { |
| 4347 var stamp = now(), |
| 4348 remaining = HOT_SPAN - (stamp - lastCalled); |
| 4349 |
| 4350 lastCalled = stamp; |
| 4351 if (remaining > 0) { |
| 4352 if (++count >= HOT_COUNT) { |
| 4353 return key; |
| 4354 } |
| 4355 } else { |
| 4356 count = 0; |
| 4357 } |
| 4358 return baseSetData(key, value); |
| 4359 }; |
| 4360 }()); |
| 4361 |
| 4362 /** |
| 4363 * A fallback implementation of `Object.keys` which creates an array of the |
| 4364 * own enumerable property names of `object`. |
| 4365 * |
| 4366 * @private |
| 4367 * @param {Object} object The object to query. |
| 4368 * @returns {Array} Returns the array of property names. |
| 4369 */ |
| 4370 function shimKeys(object) { |
| 4371 var props = keysIn(object), |
| 4372 propsLength = props.length, |
| 4373 length = propsLength && object.length; |
| 4374 |
| 4375 var allowIndexes = !!length && isLength(length) && |
| 4376 (isArray(object) || isArguments(object)); |
| 4377 |
| 4378 var index = -1, |
| 4379 result = []; |
| 4380 |
| 4381 while (++index < propsLength) { |
| 4382 var key = props[index]; |
| 4383 if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object
, key)) { |
| 4384 result.push(key); |
| 4385 } |
| 4386 } |
| 4387 return result; |
| 4388 } |
| 4389 |
| 4390 /** |
| 4391 * Converts `value` to an array-like object if it's not one. |
| 4392 * |
| 4393 * @private |
| 4394 * @param {*} value The value to process. |
| 4395 * @returns {Array|Object} Returns the array-like object. |
| 4396 */ |
| 4397 function toIterable(value) { |
| 4398 if (value == null) { |
| 4399 return []; |
| 4400 } |
| 4401 if (!isArrayLike(value)) { |
| 4402 return values(value); |
| 4403 } |
| 4404 return isObject(value) ? value : Object(value); |
| 4405 } |
| 4406 |
| 4407 /** |
| 4408 * Converts `value` to an object if it's not one. |
| 4409 * |
| 4410 * @private |
| 4411 * @param {*} value The value to process. |
| 4412 * @returns {Object} Returns the object. |
| 4413 */ |
| 4414 function toObject(value) { |
| 4415 return isObject(value) ? value : Object(value); |
| 4416 } |
| 4417 |
| 4418 /** |
| 4419 * Converts `value` to property path array if it's not one. |
| 4420 * |
| 4421 * @private |
| 4422 * @param {*} value The value to process. |
| 4423 * @returns {Array} Returns the property path array. |
| 4424 */ |
| 4425 function toPath(value) { |
| 4426 if (isArray(value)) { |
| 4427 return value; |
| 4428 } |
| 4429 var result = []; |
| 4430 baseToString(value).replace(rePropName, function(match, number, quote, str
ing) { |
| 4431 result.push(quote ? string.replace(reEscapeChar, '$1') : (number || matc
h)); |
| 4432 }); |
| 4433 return result; |
| 4434 } |
| 4435 |
| 4436 /** |
| 4437 * Creates a clone of `wrapper`. |
| 4438 * |
| 4439 * @private |
| 4440 * @param {Object} wrapper The wrapper to clone. |
| 4441 * @returns {Object} Returns the cloned wrapper. |
| 4442 */ |
| 4443 function wrapperClone(wrapper) { |
| 4444 return wrapper instanceof LazyWrapper |
| 4445 ? wrapper.clone() |
| 4446 : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wr
apper.__actions__)); |
| 4447 } |
| 4448 |
| 4449 /*------------------------------------------------------------------------*/ |
| 4450 |
| 4451 /** |
| 4452 * Creates an array of elements split into groups the length of `size`. |
| 4453 * If `collection` can't be split evenly, the final chunk will be the remain
ing |
| 4454 * elements. |
| 4455 * |
| 4456 * @static |
| 4457 * @memberOf _ |
| 4458 * @category Array |
| 4459 * @param {Array} array The array to process. |
| 4460 * @param {number} [size=1] The length of each chunk. |
| 4461 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 4462 * @returns {Array} Returns the new array containing chunks. |
| 4463 * @example |
| 4464 * |
| 4465 * _.chunk(['a', 'b', 'c', 'd'], 2); |
| 4466 * // => [['a', 'b'], ['c', 'd']] |
| 4467 * |
| 4468 * _.chunk(['a', 'b', 'c', 'd'], 3); |
| 4469 * // => [['a', 'b', 'c'], ['d']] |
| 4470 */ |
| 4471 function chunk(array, size, guard) { |
| 4472 if (guard ? isIterateeCall(array, size, guard) : size == null) { |
| 4473 size = 1; |
| 4474 } else { |
| 4475 size = nativeMax(nativeFloor(size) || 1, 1); |
| 4476 } |
| 4477 var index = 0, |
| 4478 length = array ? array.length : 0, |
| 4479 resIndex = -1, |
| 4480 result = Array(nativeCeil(length / size)); |
| 4481 |
| 4482 while (index < length) { |
| 4483 result[++resIndex] = baseSlice(array, index, (index += size)); |
| 4484 } |
| 4485 return result; |
| 4486 } |
| 4487 |
| 4488 /** |
| 4489 * Creates an array with all falsey values removed. The values `false`, `nul
l`, |
| 4490 * `0`, `""`, `undefined`, and `NaN` are falsey. |
| 4491 * |
| 4492 * @static |
| 4493 * @memberOf _ |
| 4494 * @category Array |
| 4495 * @param {Array} array The array to compact. |
| 4496 * @returns {Array} Returns the new array of filtered values. |
| 4497 * @example |
| 4498 * |
| 4499 * _.compact([0, 1, false, 2, '', 3]); |
| 4500 * // => [1, 2, 3] |
| 4501 */ |
| 4502 function compact(array) { |
| 4503 var index = -1, |
| 4504 length = array ? array.length : 0, |
| 4505 resIndex = -1, |
| 4506 result = []; |
| 4507 |
| 4508 while (++index < length) { |
| 4509 var value = array[index]; |
| 4510 if (value) { |
| 4511 result[++resIndex] = value; |
| 4512 } |
| 4513 } |
| 4514 return result; |
| 4515 } |
| 4516 |
| 4517 /** |
| 4518 * Creates an array of unique `array` values not included in the other |
| 4519 * provided arrays using [`SameValueZero`](http://ecma-international.org/ecm
a-262/6.0/#sec-samevaluezero) |
| 4520 * for equality comparisons. |
| 4521 * |
| 4522 * @static |
| 4523 * @memberOf _ |
| 4524 * @category Array |
| 4525 * @param {Array} array The array to inspect. |
| 4526 * @param {...Array} [values] The arrays of values to exclude. |
| 4527 * @returns {Array} Returns the new array of filtered values. |
| 4528 * @example |
| 4529 * |
| 4530 * _.difference([1, 2, 3], [4, 2]); |
| 4531 * // => [1, 3] |
| 4532 */ |
| 4533 var difference = restParam(function(array, values) { |
| 4534 return (isObjectLike(array) && isArrayLike(array)) |
| 4535 ? baseDifference(array, baseFlatten(values, false, true)) |
| 4536 : []; |
| 4537 }); |
| 4538 |
| 4539 /** |
| 4540 * Creates a slice of `array` with `n` elements dropped from the beginning. |
| 4541 * |
| 4542 * @static |
| 4543 * @memberOf _ |
| 4544 * @category Array |
| 4545 * @param {Array} array The array to query. |
| 4546 * @param {number} [n=1] The number of elements to drop. |
| 4547 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 4548 * @returns {Array} Returns the slice of `array`. |
| 4549 * @example |
| 4550 * |
| 4551 * _.drop([1, 2, 3]); |
| 4552 * // => [2, 3] |
| 4553 * |
| 4554 * _.drop([1, 2, 3], 2); |
| 4555 * // => [3] |
| 4556 * |
| 4557 * _.drop([1, 2, 3], 5); |
| 4558 * // => [] |
| 4559 * |
| 4560 * _.drop([1, 2, 3], 0); |
| 4561 * // => [1, 2, 3] |
| 4562 */ |
| 4563 function drop(array, n, guard) { |
| 4564 var length = array ? array.length : 0; |
| 4565 if (!length) { |
| 4566 return []; |
| 4567 } |
| 4568 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
| 4569 n = 1; |
| 4570 } |
| 4571 return baseSlice(array, n < 0 ? 0 : n); |
| 4572 } |
| 4573 |
| 4574 /** |
| 4575 * Creates a slice of `array` with `n` elements dropped from the end. |
| 4576 * |
| 4577 * @static |
| 4578 * @memberOf _ |
| 4579 * @category Array |
| 4580 * @param {Array} array The array to query. |
| 4581 * @param {number} [n=1] The number of elements to drop. |
| 4582 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 4583 * @returns {Array} Returns the slice of `array`. |
| 4584 * @example |
| 4585 * |
| 4586 * _.dropRight([1, 2, 3]); |
| 4587 * // => [1, 2] |
| 4588 * |
| 4589 * _.dropRight([1, 2, 3], 2); |
| 4590 * // => [1] |
| 4591 * |
| 4592 * _.dropRight([1, 2, 3], 5); |
| 4593 * // => [] |
| 4594 * |
| 4595 * _.dropRight([1, 2, 3], 0); |
| 4596 * // => [1, 2, 3] |
| 4597 */ |
| 4598 function dropRight(array, n, guard) { |
| 4599 var length = array ? array.length : 0; |
| 4600 if (!length) { |
| 4601 return []; |
| 4602 } |
| 4603 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
| 4604 n = 1; |
| 4605 } |
| 4606 n = length - (+n || 0); |
| 4607 return baseSlice(array, 0, n < 0 ? 0 : n); |
| 4608 } |
| 4609 |
| 4610 /** |
| 4611 * Creates a slice of `array` excluding elements dropped from the end. |
| 4612 * Elements are dropped until `predicate` returns falsey. The predicate is |
| 4613 * bound to `thisArg` and invoked with three arguments: (value, index, array
). |
| 4614 * |
| 4615 * If a property name is provided for `predicate` the created `_.property` |
| 4616 * style callback returns the property value of the given element. |
| 4617 * |
| 4618 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 4619 * style callback returns `true` for elements that have a matching property |
| 4620 * value, else `false`. |
| 4621 * |
| 4622 * If an object is provided for `predicate` the created `_.matches` style |
| 4623 * callback returns `true` for elements that match the properties of the giv
en |
| 4624 * object, else `false`. |
| 4625 * |
| 4626 * @static |
| 4627 * @memberOf _ |
| 4628 * @category Array |
| 4629 * @param {Array} array The array to query. |
| 4630 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 4631 * per iteration. |
| 4632 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 4633 * @returns {Array} Returns the slice of `array`. |
| 4634 * @example |
| 4635 * |
| 4636 * _.dropRightWhile([1, 2, 3], function(n) { |
| 4637 * return n > 1; |
| 4638 * }); |
| 4639 * // => [1] |
| 4640 * |
| 4641 * var users = [ |
| 4642 * { 'user': 'barney', 'active': true }, |
| 4643 * { 'user': 'fred', 'active': false }, |
| 4644 * { 'user': 'pebbles', 'active': false } |
| 4645 * ]; |
| 4646 * |
| 4647 * // using the `_.matches` callback shorthand |
| 4648 * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }),
'user'); |
| 4649 * // => ['barney', 'fred'] |
| 4650 * |
| 4651 * // using the `_.matchesProperty` callback shorthand |
| 4652 * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); |
| 4653 * // => ['barney'] |
| 4654 * |
| 4655 * // using the `_.property` callback shorthand |
| 4656 * _.pluck(_.dropRightWhile(users, 'active'), 'user'); |
| 4657 * // => ['barney', 'fred', 'pebbles'] |
| 4658 */ |
| 4659 function dropRightWhile(array, predicate, thisArg) { |
| 4660 return (array && array.length) |
| 4661 ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) |
| 4662 : []; |
| 4663 } |
| 4664 |
| 4665 /** |
| 4666 * Creates a slice of `array` excluding elements dropped from the beginning. |
| 4667 * Elements are dropped until `predicate` returns falsey. The predicate is |
| 4668 * bound to `thisArg` and invoked with three arguments: (value, index, array
). |
| 4669 * |
| 4670 * If a property name is provided for `predicate` the created `_.property` |
| 4671 * style callback returns the property value of the given element. |
| 4672 * |
| 4673 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 4674 * style callback returns `true` for elements that have a matching property |
| 4675 * value, else `false`. |
| 4676 * |
| 4677 * If an object is provided for `predicate` the created `_.matches` style |
| 4678 * callback returns `true` for elements that have the properties of the give
n |
| 4679 * object, else `false`. |
| 4680 * |
| 4681 * @static |
| 4682 * @memberOf _ |
| 4683 * @category Array |
| 4684 * @param {Array} array The array to query. |
| 4685 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 4686 * per iteration. |
| 4687 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 4688 * @returns {Array} Returns the slice of `array`. |
| 4689 * @example |
| 4690 * |
| 4691 * _.dropWhile([1, 2, 3], function(n) { |
| 4692 * return n < 3; |
| 4693 * }); |
| 4694 * // => [3] |
| 4695 * |
| 4696 * var users = [ |
| 4697 * { 'user': 'barney', 'active': false }, |
| 4698 * { 'user': 'fred', 'active': false }, |
| 4699 * { 'user': 'pebbles', 'active': true } |
| 4700 * ]; |
| 4701 * |
| 4702 * // using the `_.matches` callback shorthand |
| 4703 * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'
); |
| 4704 * // => ['fred', 'pebbles'] |
| 4705 * |
| 4706 * // using the `_.matchesProperty` callback shorthand |
| 4707 * _.pluck(_.dropWhile(users, 'active', false), 'user'); |
| 4708 * // => ['pebbles'] |
| 4709 * |
| 4710 * // using the `_.property` callback shorthand |
| 4711 * _.pluck(_.dropWhile(users, 'active'), 'user'); |
| 4712 * // => ['barney', 'fred', 'pebbles'] |
| 4713 */ |
| 4714 function dropWhile(array, predicate, thisArg) { |
| 4715 return (array && array.length) |
| 4716 ? baseWhile(array, getCallback(predicate, thisArg, 3), true) |
| 4717 : []; |
| 4718 } |
| 4719 |
| 4720 /** |
| 4721 * Fills elements of `array` with `value` from `start` up to, but not |
| 4722 * including, `end`. |
| 4723 * |
| 4724 * **Note:** This method mutates `array`. |
| 4725 * |
| 4726 * @static |
| 4727 * @memberOf _ |
| 4728 * @category Array |
| 4729 * @param {Array} array The array to fill. |
| 4730 * @param {*} value The value to fill `array` with. |
| 4731 * @param {number} [start=0] The start position. |
| 4732 * @param {number} [end=array.length] The end position. |
| 4733 * @returns {Array} Returns `array`. |
| 4734 * @example |
| 4735 * |
| 4736 * var array = [1, 2, 3]; |
| 4737 * |
| 4738 * _.fill(array, 'a'); |
| 4739 * console.log(array); |
| 4740 * // => ['a', 'a', 'a'] |
| 4741 * |
| 4742 * _.fill(Array(3), 2); |
| 4743 * // => [2, 2, 2] |
| 4744 * |
| 4745 * _.fill([4, 6, 8], '*', 1, 2); |
| 4746 * // => [4, '*', 8] |
| 4747 */ |
| 4748 function fill(array, value, start, end) { |
| 4749 var length = array ? array.length : 0; |
| 4750 if (!length) { |
| 4751 return []; |
| 4752 } |
| 4753 if (start && typeof start != 'number' && isIterateeCall(array, value, star
t)) { |
| 4754 start = 0; |
| 4755 end = length; |
| 4756 } |
| 4757 return baseFill(array, value, start, end); |
| 4758 } |
| 4759 |
| 4760 /** |
| 4761 * This method is like `_.find` except that it returns the index of the firs
t |
| 4762 * element `predicate` returns truthy for instead of the element itself. |
| 4763 * |
| 4764 * If a property name is provided for `predicate` the created `_.property` |
| 4765 * style callback returns the property value of the given element. |
| 4766 * |
| 4767 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 4768 * style callback returns `true` for elements that have a matching property |
| 4769 * value, else `false`. |
| 4770 * |
| 4771 * If an object is provided for `predicate` the created `_.matches` style |
| 4772 * callback returns `true` for elements that have the properties of the give
n |
| 4773 * object, else `false`. |
| 4774 * |
| 4775 * @static |
| 4776 * @memberOf _ |
| 4777 * @category Array |
| 4778 * @param {Array} array The array to search. |
| 4779 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 4780 * per iteration. |
| 4781 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 4782 * @returns {number} Returns the index of the found element, else `-1`. |
| 4783 * @example |
| 4784 * |
| 4785 * var users = [ |
| 4786 * { 'user': 'barney', 'active': false }, |
| 4787 * { 'user': 'fred', 'active': false }, |
| 4788 * { 'user': 'pebbles', 'active': true } |
| 4789 * ]; |
| 4790 * |
| 4791 * _.findIndex(users, function(chr) { |
| 4792 * return chr.user == 'barney'; |
| 4793 * }); |
| 4794 * // => 0 |
| 4795 * |
| 4796 * // using the `_.matches` callback shorthand |
| 4797 * _.findIndex(users, { 'user': 'fred', 'active': false }); |
| 4798 * // => 1 |
| 4799 * |
| 4800 * // using the `_.matchesProperty` callback shorthand |
| 4801 * _.findIndex(users, 'active', false); |
| 4802 * // => 0 |
| 4803 * |
| 4804 * // using the `_.property` callback shorthand |
| 4805 * _.findIndex(users, 'active'); |
| 4806 * // => 2 |
| 4807 */ |
| 4808 var findIndex = createFindIndex(); |
| 4809 |
| 4810 /** |
| 4811 * This method is like `_.findIndex` except that it iterates over elements |
| 4812 * of `collection` from right to left. |
| 4813 * |
| 4814 * If a property name is provided for `predicate` the created `_.property` |
| 4815 * style callback returns the property value of the given element. |
| 4816 * |
| 4817 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 4818 * style callback returns `true` for elements that have a matching property |
| 4819 * value, else `false`. |
| 4820 * |
| 4821 * If an object is provided for `predicate` the created `_.matches` style |
| 4822 * callback returns `true` for elements that have the properties of the give
n |
| 4823 * object, else `false`. |
| 4824 * |
| 4825 * @static |
| 4826 * @memberOf _ |
| 4827 * @category Array |
| 4828 * @param {Array} array The array to search. |
| 4829 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 4830 * per iteration. |
| 4831 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 4832 * @returns {number} Returns the index of the found element, else `-1`. |
| 4833 * @example |
| 4834 * |
| 4835 * var users = [ |
| 4836 * { 'user': 'barney', 'active': true }, |
| 4837 * { 'user': 'fred', 'active': false }, |
| 4838 * { 'user': 'pebbles', 'active': false } |
| 4839 * ]; |
| 4840 * |
| 4841 * _.findLastIndex(users, function(chr) { |
| 4842 * return chr.user == 'pebbles'; |
| 4843 * }); |
| 4844 * // => 2 |
| 4845 * |
| 4846 * // using the `_.matches` callback shorthand |
| 4847 * _.findLastIndex(users, { 'user': 'barney', 'active': true }); |
| 4848 * // => 0 |
| 4849 * |
| 4850 * // using the `_.matchesProperty` callback shorthand |
| 4851 * _.findLastIndex(users, 'active', false); |
| 4852 * // => 2 |
| 4853 * |
| 4854 * // using the `_.property` callback shorthand |
| 4855 * _.findLastIndex(users, 'active'); |
| 4856 * // => 0 |
| 4857 */ |
| 4858 var findLastIndex = createFindIndex(true); |
| 4859 |
| 4860 /** |
| 4861 * Gets the first element of `array`. |
| 4862 * |
| 4863 * @static |
| 4864 * @memberOf _ |
| 4865 * @alias head |
| 4866 * @category Array |
| 4867 * @param {Array} array The array to query. |
| 4868 * @returns {*} Returns the first element of `array`. |
| 4869 * @example |
| 4870 * |
| 4871 * _.first([1, 2, 3]); |
| 4872 * // => 1 |
| 4873 * |
| 4874 * _.first([]); |
| 4875 * // => undefined |
| 4876 */ |
| 4877 function first(array) { |
| 4878 return array ? array[0] : undefined; |
| 4879 } |
| 4880 |
| 4881 /** |
| 4882 * Flattens a nested array. If `isDeep` is `true` the array is recursively |
| 4883 * flattened, otherwise it's only flattened a single level. |
| 4884 * |
| 4885 * @static |
| 4886 * @memberOf _ |
| 4887 * @category Array |
| 4888 * @param {Array} array The array to flatten. |
| 4889 * @param {boolean} [isDeep] Specify a deep flatten. |
| 4890 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 4891 * @returns {Array} Returns the new flattened array. |
| 4892 * @example |
| 4893 * |
| 4894 * _.flatten([1, [2, 3, [4]]]); |
| 4895 * // => [1, 2, 3, [4]] |
| 4896 * |
| 4897 * // using `isDeep` |
| 4898 * _.flatten([1, [2, 3, [4]]], true); |
| 4899 * // => [1, 2, 3, 4] |
| 4900 */ |
| 4901 function flatten(array, isDeep, guard) { |
| 4902 var length = array ? array.length : 0; |
| 4903 if (guard && isIterateeCall(array, isDeep, guard)) { |
| 4904 isDeep = false; |
| 4905 } |
| 4906 return length ? baseFlatten(array, isDeep) : []; |
| 4907 } |
| 4908 |
| 4909 /** |
| 4910 * Recursively flattens a nested array. |
| 4911 * |
| 4912 * @static |
| 4913 * @memberOf _ |
| 4914 * @category Array |
| 4915 * @param {Array} array The array to recursively flatten. |
| 4916 * @returns {Array} Returns the new flattened array. |
| 4917 * @example |
| 4918 * |
| 4919 * _.flattenDeep([1, [2, 3, [4]]]); |
| 4920 * // => [1, 2, 3, 4] |
| 4921 */ |
| 4922 function flattenDeep(array) { |
| 4923 var length = array ? array.length : 0; |
| 4924 return length ? baseFlatten(array, true) : []; |
| 4925 } |
| 4926 |
| 4927 /** |
| 4928 * Gets the index at which the first occurrence of `value` is found in `arra
y` |
| 4929 * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-s
amevaluezero) |
| 4930 * for equality comparisons. If `fromIndex` is negative, it's used as the of
fset |
| 4931 * from the end of `array`. If `array` is sorted providing `true` for `fromI
ndex` |
| 4932 * performs a faster binary search. |
| 4933 * |
| 4934 * @static |
| 4935 * @memberOf _ |
| 4936 * @category Array |
| 4937 * @param {Array} array The array to search. |
| 4938 * @param {*} value The value to search for. |
| 4939 * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
| 4940 * to perform a binary search on a sorted array. |
| 4941 * @returns {number} Returns the index of the matched value, else `-1`. |
| 4942 * @example |
| 4943 * |
| 4944 * _.indexOf([1, 2, 1, 2], 2); |
| 4945 * // => 1 |
| 4946 * |
| 4947 * // using `fromIndex` |
| 4948 * _.indexOf([1, 2, 1, 2], 2, 2); |
| 4949 * // => 3 |
| 4950 * |
| 4951 * // performing a binary search |
| 4952 * _.indexOf([1, 1, 2, 2], 2, true); |
| 4953 * // => 2 |
| 4954 */ |
| 4955 function indexOf(array, value, fromIndex) { |
| 4956 var length = array ? array.length : 0; |
| 4957 if (!length) { |
| 4958 return -1; |
| 4959 } |
| 4960 if (typeof fromIndex == 'number') { |
| 4961 fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex
; |
| 4962 } else if (fromIndex) { |
| 4963 var index = binaryIndex(array, value); |
| 4964 if (index < length && |
| 4965 (value === value ? (value === array[index]) : (array[index] !== arra
y[index]))) { |
| 4966 return index; |
| 4967 } |
| 4968 return -1; |
| 4969 } |
| 4970 return baseIndexOf(array, value, fromIndex || 0); |
| 4971 } |
| 4972 |
| 4973 /** |
| 4974 * Gets all but the last element of `array`. |
| 4975 * |
| 4976 * @static |
| 4977 * @memberOf _ |
| 4978 * @category Array |
| 4979 * @param {Array} array The array to query. |
| 4980 * @returns {Array} Returns the slice of `array`. |
| 4981 * @example |
| 4982 * |
| 4983 * _.initial([1, 2, 3]); |
| 4984 * // => [1, 2] |
| 4985 */ |
| 4986 function initial(array) { |
| 4987 return dropRight(array, 1); |
| 4988 } |
| 4989 |
| 4990 /** |
| 4991 * Creates an array of unique values that are included in all of the provide
d |
| 4992 * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0
/#sec-samevaluezero) |
| 4993 * for equality comparisons. |
| 4994 * |
| 4995 * @static |
| 4996 * @memberOf _ |
| 4997 * @category Array |
| 4998 * @param {...Array} [arrays] The arrays to inspect. |
| 4999 * @returns {Array} Returns the new array of shared values. |
| 5000 * @example |
| 5001 * _.intersection([1, 2], [4, 2], [2, 1]); |
| 5002 * // => [2] |
| 5003 */ |
| 5004 var intersection = restParam(function(arrays) { |
| 5005 var othLength = arrays.length, |
| 5006 othIndex = othLength, |
| 5007 caches = Array(length), |
| 5008 indexOf = getIndexOf(), |
| 5009 isCommon = indexOf === baseIndexOf, |
| 5010 result = []; |
| 5011 |
| 5012 while (othIndex--) { |
| 5013 var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? v
alue : []; |
| 5014 caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIn
dex && value) : null; |
| 5015 } |
| 5016 var array = arrays[0], |
| 5017 index = -1, |
| 5018 length = array ? array.length : 0, |
| 5019 seen = caches[0]; |
| 5020 |
| 5021 outer: |
| 5022 while (++index < length) { |
| 5023 value = array[index]; |
| 5024 if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0)
{ |
| 5025 var othIndex = othLength; |
| 5026 while (--othIndex) { |
| 5027 var cache = caches[othIndex]; |
| 5028 if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex],
value, 0)) < 0) { |
| 5029 continue outer; |
| 5030 } |
| 5031 } |
| 5032 if (seen) { |
| 5033 seen.push(value); |
| 5034 } |
| 5035 result.push(value); |
| 5036 } |
| 5037 } |
| 5038 return result; |
| 5039 }); |
| 5040 |
| 5041 /** |
| 5042 * Gets the last element of `array`. |
| 5043 * |
| 5044 * @static |
| 5045 * @memberOf _ |
| 5046 * @category Array |
| 5047 * @param {Array} array The array to query. |
| 5048 * @returns {*} Returns the last element of `array`. |
| 5049 * @example |
| 5050 * |
| 5051 * _.last([1, 2, 3]); |
| 5052 * // => 3 |
| 5053 */ |
| 5054 function last(array) { |
| 5055 var length = array ? array.length : 0; |
| 5056 return length ? array[length - 1] : undefined; |
| 5057 } |
| 5058 |
| 5059 /** |
| 5060 * This method is like `_.indexOf` except that it iterates over elements of |
| 5061 * `array` from right to left. |
| 5062 * |
| 5063 * @static |
| 5064 * @memberOf _ |
| 5065 * @category Array |
| 5066 * @param {Array} array The array to search. |
| 5067 * @param {*} value The value to search for. |
| 5068 * @param {boolean|number} [fromIndex=array.length-1] The index to search fr
om |
| 5069 * or `true` to perform a binary search on a sorted array. |
| 5070 * @returns {number} Returns the index of the matched value, else `-1`. |
| 5071 * @example |
| 5072 * |
| 5073 * _.lastIndexOf([1, 2, 1, 2], 2); |
| 5074 * // => 3 |
| 5075 * |
| 5076 * // using `fromIndex` |
| 5077 * _.lastIndexOf([1, 2, 1, 2], 2, 2); |
| 5078 * // => 1 |
| 5079 * |
| 5080 * // performing a binary search |
| 5081 * _.lastIndexOf([1, 1, 2, 2], 2, true); |
| 5082 * // => 3 |
| 5083 */ |
| 5084 function lastIndexOf(array, value, fromIndex) { |
| 5085 var length = array ? array.length : 0; |
| 5086 if (!length) { |
| 5087 return -1; |
| 5088 } |
| 5089 var index = length; |
| 5090 if (typeof fromIndex == 'number') { |
| 5091 index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fr
omIndex || 0, length - 1)) + 1; |
| 5092 } else if (fromIndex) { |
| 5093 index = binaryIndex(array, value, true) - 1; |
| 5094 var other = array[index]; |
| 5095 if (value === value ? (value === other) : (other !== other)) { |
| 5096 return index; |
| 5097 } |
| 5098 return -1; |
| 5099 } |
| 5100 if (value !== value) { |
| 5101 return indexOfNaN(array, index, true); |
| 5102 } |
| 5103 while (index--) { |
| 5104 if (array[index] === value) { |
| 5105 return index; |
| 5106 } |
| 5107 } |
| 5108 return -1; |
| 5109 } |
| 5110 |
| 5111 /** |
| 5112 * Removes all provided values from `array` using |
| 5113 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-sameval
uezero) |
| 5114 * for equality comparisons. |
| 5115 * |
| 5116 * **Note:** Unlike `_.without`, this method mutates `array`. |
| 5117 * |
| 5118 * @static |
| 5119 * @memberOf _ |
| 5120 * @category Array |
| 5121 * @param {Array} array The array to modify. |
| 5122 * @param {...*} [values] The values to remove. |
| 5123 * @returns {Array} Returns `array`. |
| 5124 * @example |
| 5125 * |
| 5126 * var array = [1, 2, 3, 1, 2, 3]; |
| 5127 * |
| 5128 * _.pull(array, 2, 3); |
| 5129 * console.log(array); |
| 5130 * // => [1, 1] |
| 5131 */ |
| 5132 function pull() { |
| 5133 var args = arguments, |
| 5134 array = args[0]; |
| 5135 |
| 5136 if (!(array && array.length)) { |
| 5137 return array; |
| 5138 } |
| 5139 var index = 0, |
| 5140 indexOf = getIndexOf(), |
| 5141 length = args.length; |
| 5142 |
| 5143 while (++index < length) { |
| 5144 var fromIndex = 0, |
| 5145 value = args[index]; |
| 5146 |
| 5147 while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { |
| 5148 splice.call(array, fromIndex, 1); |
| 5149 } |
| 5150 } |
| 5151 return array; |
| 5152 } |
| 5153 |
| 5154 /** |
| 5155 * Removes elements from `array` corresponding to the given indexes and retu
rns |
| 5156 * an array of the removed elements. Indexes may be specified as an array of |
| 5157 * indexes or as individual arguments. |
| 5158 * |
| 5159 * **Note:** Unlike `_.at`, this method mutates `array`. |
| 5160 * |
| 5161 * @static |
| 5162 * @memberOf _ |
| 5163 * @category Array |
| 5164 * @param {Array} array The array to modify. |
| 5165 * @param {...(number|number[])} [indexes] The indexes of elements to remove
, |
| 5166 * specified as individual indexes or arrays of indexes. |
| 5167 * @returns {Array} Returns the new array of removed elements. |
| 5168 * @example |
| 5169 * |
| 5170 * var array = [5, 10, 15, 20]; |
| 5171 * var evens = _.pullAt(array, 1, 3); |
| 5172 * |
| 5173 * console.log(array); |
| 5174 * // => [5, 15] |
| 5175 * |
| 5176 * console.log(evens); |
| 5177 * // => [10, 20] |
| 5178 */ |
| 5179 var pullAt = restParam(function(array, indexes) { |
| 5180 indexes = baseFlatten(indexes); |
| 5181 |
| 5182 var result = baseAt(array, indexes); |
| 5183 basePullAt(array, indexes.sort(baseCompareAscending)); |
| 5184 return result; |
| 5185 }); |
| 5186 |
| 5187 /** |
| 5188 * Removes all elements from `array` that `predicate` returns truthy for |
| 5189 * and returns an array of the removed elements. The predicate is bound to |
| 5190 * `thisArg` and invoked with three arguments: (value, index, array). |
| 5191 * |
| 5192 * If a property name is provided for `predicate` the created `_.property` |
| 5193 * style callback returns the property value of the given element. |
| 5194 * |
| 5195 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 5196 * style callback returns `true` for elements that have a matching property |
| 5197 * value, else `false`. |
| 5198 * |
| 5199 * If an object is provided for `predicate` the created `_.matches` style |
| 5200 * callback returns `true` for elements that have the properties of the give
n |
| 5201 * object, else `false`. |
| 5202 * |
| 5203 * **Note:** Unlike `_.filter`, this method mutates `array`. |
| 5204 * |
| 5205 * @static |
| 5206 * @memberOf _ |
| 5207 * @category Array |
| 5208 * @param {Array} array The array to modify. |
| 5209 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 5210 * per iteration. |
| 5211 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 5212 * @returns {Array} Returns the new array of removed elements. |
| 5213 * @example |
| 5214 * |
| 5215 * var array = [1, 2, 3, 4]; |
| 5216 * var evens = _.remove(array, function(n) { |
| 5217 * return n % 2 == 0; |
| 5218 * }); |
| 5219 * |
| 5220 * console.log(array); |
| 5221 * // => [1, 3] |
| 5222 * |
| 5223 * console.log(evens); |
| 5224 * // => [2, 4] |
| 5225 */ |
| 5226 function remove(array, predicate, thisArg) { |
| 5227 var result = []; |
| 5228 if (!(array && array.length)) { |
| 5229 return result; |
| 5230 } |
| 5231 var index = -1, |
| 5232 indexes = [], |
| 5233 length = array.length; |
| 5234 |
| 5235 predicate = getCallback(predicate, thisArg, 3); |
| 5236 while (++index < length) { |
| 5237 var value = array[index]; |
| 5238 if (predicate(value, index, array)) { |
| 5239 result.push(value); |
| 5240 indexes.push(index); |
| 5241 } |
| 5242 } |
| 5243 basePullAt(array, indexes); |
| 5244 return result; |
| 5245 } |
| 5246 |
| 5247 /** |
| 5248 * Gets all but the first element of `array`. |
| 5249 * |
| 5250 * @static |
| 5251 * @memberOf _ |
| 5252 * @alias tail |
| 5253 * @category Array |
| 5254 * @param {Array} array The array to query. |
| 5255 * @returns {Array} Returns the slice of `array`. |
| 5256 * @example |
| 5257 * |
| 5258 * _.rest([1, 2, 3]); |
| 5259 * // => [2, 3] |
| 5260 */ |
| 5261 function rest(array) { |
| 5262 return drop(array, 1); |
| 5263 } |
| 5264 |
| 5265 /** |
| 5266 * Creates a slice of `array` from `start` up to, but not including, `end`. |
| 5267 * |
| 5268 * **Note:** This method is used instead of `Array#slice` to support node |
| 5269 * lists in IE < 9 and to ensure dense arrays are returned. |
| 5270 * |
| 5271 * @static |
| 5272 * @memberOf _ |
| 5273 * @category Array |
| 5274 * @param {Array} array The array to slice. |
| 5275 * @param {number} [start=0] The start position. |
| 5276 * @param {number} [end=array.length] The end position. |
| 5277 * @returns {Array} Returns the slice of `array`. |
| 5278 */ |
| 5279 function slice(array, start, end) { |
| 5280 var length = array ? array.length : 0; |
| 5281 if (!length) { |
| 5282 return []; |
| 5283 } |
| 5284 if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { |
| 5285 start = 0; |
| 5286 end = length; |
| 5287 } |
| 5288 return baseSlice(array, start, end); |
| 5289 } |
| 5290 |
| 5291 /** |
| 5292 * Uses a binary search to determine the lowest index at which `value` shoul
d |
| 5293 * be inserted into `array` in order to maintain its sort order. If an itera
tee |
| 5294 * function is provided it's invoked for `value` and each element of `array` |
| 5295 * to compute their sort ranking. The iteratee is bound to `thisArg` and |
| 5296 * invoked with one argument; (value). |
| 5297 * |
| 5298 * If a property name is provided for `iteratee` the created `_.property` |
| 5299 * style callback returns the property value of the given element. |
| 5300 * |
| 5301 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 5302 * style callback returns `true` for elements that have a matching property |
| 5303 * value, else `false`. |
| 5304 * |
| 5305 * If an object is provided for `iteratee` the created `_.matches` style |
| 5306 * callback returns `true` for elements that have the properties of the give
n |
| 5307 * object, else `false`. |
| 5308 * |
| 5309 * @static |
| 5310 * @memberOf _ |
| 5311 * @category Array |
| 5312 * @param {Array} array The sorted array to inspect. |
| 5313 * @param {*} value The value to evaluate. |
| 5314 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 5315 * per iteration. |
| 5316 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 5317 * @returns {number} Returns the index at which `value` should be inserted |
| 5318 * into `array`. |
| 5319 * @example |
| 5320 * |
| 5321 * _.sortedIndex([30, 50], 40); |
| 5322 * // => 1 |
| 5323 * |
| 5324 * _.sortedIndex([4, 4, 5, 5], 5); |
| 5325 * // => 2 |
| 5326 * |
| 5327 * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; |
| 5328 * |
| 5329 * // using an iteratee function |
| 5330 * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { |
| 5331 * return this.data[word]; |
| 5332 * }, dict); |
| 5333 * // => 1 |
| 5334 * |
| 5335 * // using the `_.property` callback shorthand |
| 5336 * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); |
| 5337 * // => 1 |
| 5338 */ |
| 5339 var sortedIndex = createSortedIndex(); |
| 5340 |
| 5341 /** |
| 5342 * This method is like `_.sortedIndex` except that it returns the highest |
| 5343 * index at which `value` should be inserted into `array` in order to |
| 5344 * maintain its sort order. |
| 5345 * |
| 5346 * @static |
| 5347 * @memberOf _ |
| 5348 * @category Array |
| 5349 * @param {Array} array The sorted array to inspect. |
| 5350 * @param {*} value The value to evaluate. |
| 5351 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 5352 * per iteration. |
| 5353 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 5354 * @returns {number} Returns the index at which `value` should be inserted |
| 5355 * into `array`. |
| 5356 * @example |
| 5357 * |
| 5358 * _.sortedLastIndex([4, 4, 5, 5], 5); |
| 5359 * // => 4 |
| 5360 */ |
| 5361 var sortedLastIndex = createSortedIndex(true); |
| 5362 |
| 5363 /** |
| 5364 * Creates a slice of `array` with `n` elements taken from the beginning. |
| 5365 * |
| 5366 * @static |
| 5367 * @memberOf _ |
| 5368 * @category Array |
| 5369 * @param {Array} array The array to query. |
| 5370 * @param {number} [n=1] The number of elements to take. |
| 5371 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 5372 * @returns {Array} Returns the slice of `array`. |
| 5373 * @example |
| 5374 * |
| 5375 * _.take([1, 2, 3]); |
| 5376 * // => [1] |
| 5377 * |
| 5378 * _.take([1, 2, 3], 2); |
| 5379 * // => [1, 2] |
| 5380 * |
| 5381 * _.take([1, 2, 3], 5); |
| 5382 * // => [1, 2, 3] |
| 5383 * |
| 5384 * _.take([1, 2, 3], 0); |
| 5385 * // => [] |
| 5386 */ |
| 5387 function take(array, n, guard) { |
| 5388 var length = array ? array.length : 0; |
| 5389 if (!length) { |
| 5390 return []; |
| 5391 } |
| 5392 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
| 5393 n = 1; |
| 5394 } |
| 5395 return baseSlice(array, 0, n < 0 ? 0 : n); |
| 5396 } |
| 5397 |
| 5398 /** |
| 5399 * Creates a slice of `array` with `n` elements taken from the end. |
| 5400 * |
| 5401 * @static |
| 5402 * @memberOf _ |
| 5403 * @category Array |
| 5404 * @param {Array} array The array to query. |
| 5405 * @param {number} [n=1] The number of elements to take. |
| 5406 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 5407 * @returns {Array} Returns the slice of `array`. |
| 5408 * @example |
| 5409 * |
| 5410 * _.takeRight([1, 2, 3]); |
| 5411 * // => [3] |
| 5412 * |
| 5413 * _.takeRight([1, 2, 3], 2); |
| 5414 * // => [2, 3] |
| 5415 * |
| 5416 * _.takeRight([1, 2, 3], 5); |
| 5417 * // => [1, 2, 3] |
| 5418 * |
| 5419 * _.takeRight([1, 2, 3], 0); |
| 5420 * // => [] |
| 5421 */ |
| 5422 function takeRight(array, n, guard) { |
| 5423 var length = array ? array.length : 0; |
| 5424 if (!length) { |
| 5425 return []; |
| 5426 } |
| 5427 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
| 5428 n = 1; |
| 5429 } |
| 5430 n = length - (+n || 0); |
| 5431 return baseSlice(array, n < 0 ? 0 : n); |
| 5432 } |
| 5433 |
| 5434 /** |
| 5435 * Creates a slice of `array` with elements taken from the end. Elements are |
| 5436 * taken until `predicate` returns falsey. The predicate is bound to `thisAr
g` |
| 5437 * and invoked with three arguments: (value, index, array). |
| 5438 * |
| 5439 * If a property name is provided for `predicate` the created `_.property` |
| 5440 * style callback returns the property value of the given element. |
| 5441 * |
| 5442 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 5443 * style callback returns `true` for elements that have a matching property |
| 5444 * value, else `false`. |
| 5445 * |
| 5446 * If an object is provided for `predicate` the created `_.matches` style |
| 5447 * callback returns `true` for elements that have the properties of the give
n |
| 5448 * object, else `false`. |
| 5449 * |
| 5450 * @static |
| 5451 * @memberOf _ |
| 5452 * @category Array |
| 5453 * @param {Array} array The array to query. |
| 5454 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 5455 * per iteration. |
| 5456 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 5457 * @returns {Array} Returns the slice of `array`. |
| 5458 * @example |
| 5459 * |
| 5460 * _.takeRightWhile([1, 2, 3], function(n) { |
| 5461 * return n > 1; |
| 5462 * }); |
| 5463 * // => [2, 3] |
| 5464 * |
| 5465 * var users = [ |
| 5466 * { 'user': 'barney', 'active': true }, |
| 5467 * { 'user': 'fred', 'active': false }, |
| 5468 * { 'user': 'pebbles', 'active': false } |
| 5469 * ]; |
| 5470 * |
| 5471 * // using the `_.matches` callback shorthand |
| 5472 * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }),
'user'); |
| 5473 * // => ['pebbles'] |
| 5474 * |
| 5475 * // using the `_.matchesProperty` callback shorthand |
| 5476 * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); |
| 5477 * // => ['fred', 'pebbles'] |
| 5478 * |
| 5479 * // using the `_.property` callback shorthand |
| 5480 * _.pluck(_.takeRightWhile(users, 'active'), 'user'); |
| 5481 * // => [] |
| 5482 */ |
| 5483 function takeRightWhile(array, predicate, thisArg) { |
| 5484 return (array && array.length) |
| 5485 ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) |
| 5486 : []; |
| 5487 } |
| 5488 |
| 5489 /** |
| 5490 * Creates a slice of `array` with elements taken from the beginning. Elemen
ts |
| 5491 * are taken until `predicate` returns falsey. The predicate is bound to |
| 5492 * `thisArg` and invoked with three arguments: (value, index, array). |
| 5493 * |
| 5494 * If a property name is provided for `predicate` the created `_.property` |
| 5495 * style callback returns the property value of the given element. |
| 5496 * |
| 5497 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 5498 * style callback returns `true` for elements that have a matching property |
| 5499 * value, else `false`. |
| 5500 * |
| 5501 * If an object is provided for `predicate` the created `_.matches` style |
| 5502 * callback returns `true` for elements that have the properties of the give
n |
| 5503 * object, else `false`. |
| 5504 * |
| 5505 * @static |
| 5506 * @memberOf _ |
| 5507 * @category Array |
| 5508 * @param {Array} array The array to query. |
| 5509 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 5510 * per iteration. |
| 5511 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 5512 * @returns {Array} Returns the slice of `array`. |
| 5513 * @example |
| 5514 * |
| 5515 * _.takeWhile([1, 2, 3], function(n) { |
| 5516 * return n < 3; |
| 5517 * }); |
| 5518 * // => [1, 2] |
| 5519 * |
| 5520 * var users = [ |
| 5521 * { 'user': 'barney', 'active': false }, |
| 5522 * { 'user': 'fred', 'active': false}, |
| 5523 * { 'user': 'pebbles', 'active': true } |
| 5524 * ]; |
| 5525 * |
| 5526 * // using the `_.matches` callback shorthand |
| 5527 * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'
); |
| 5528 * // => ['barney'] |
| 5529 * |
| 5530 * // using the `_.matchesProperty` callback shorthand |
| 5531 * _.pluck(_.takeWhile(users, 'active', false), 'user'); |
| 5532 * // => ['barney', 'fred'] |
| 5533 * |
| 5534 * // using the `_.property` callback shorthand |
| 5535 * _.pluck(_.takeWhile(users, 'active'), 'user'); |
| 5536 * // => [] |
| 5537 */ |
| 5538 function takeWhile(array, predicate, thisArg) { |
| 5539 return (array && array.length) |
| 5540 ? baseWhile(array, getCallback(predicate, thisArg, 3)) |
| 5541 : []; |
| 5542 } |
| 5543 |
| 5544 /** |
| 5545 * Creates an array of unique values, in order, from all of the provided arr
ays |
| 5546 * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-s
amevaluezero) |
| 5547 * for equality comparisons. |
| 5548 * |
| 5549 * @static |
| 5550 * @memberOf _ |
| 5551 * @category Array |
| 5552 * @param {...Array} [arrays] The arrays to inspect. |
| 5553 * @returns {Array} Returns the new array of combined values. |
| 5554 * @example |
| 5555 * |
| 5556 * _.union([1, 2], [4, 2], [2, 1]); |
| 5557 * // => [1, 2, 4] |
| 5558 */ |
| 5559 var union = restParam(function(arrays) { |
| 5560 return baseUniq(baseFlatten(arrays, false, true)); |
| 5561 }); |
| 5562 |
| 5563 /** |
| 5564 * Creates a duplicate-free version of an array, using |
| 5565 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-sameval
uezero) |
| 5566 * for equality comparisons, in which only the first occurence of each eleme
nt |
| 5567 * is kept. Providing `true` for `isSorted` performs a faster search algorit
hm |
| 5568 * for sorted arrays. If an iteratee function is provided it's invoked for |
| 5569 * each element in the array to generate the criterion by which uniqueness |
| 5570 * is computed. The `iteratee` is bound to `thisArg` and invoked with three |
| 5571 * arguments: (value, index, array). |
| 5572 * |
| 5573 * If a property name is provided for `iteratee` the created `_.property` |
| 5574 * style callback returns the property value of the given element. |
| 5575 * |
| 5576 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 5577 * style callback returns `true` for elements that have a matching property |
| 5578 * value, else `false`. |
| 5579 * |
| 5580 * If an object is provided for `iteratee` the created `_.matches` style |
| 5581 * callback returns `true` for elements that have the properties of the give
n |
| 5582 * object, else `false`. |
| 5583 * |
| 5584 * @static |
| 5585 * @memberOf _ |
| 5586 * @alias unique |
| 5587 * @category Array |
| 5588 * @param {Array} array The array to inspect. |
| 5589 * @param {boolean} [isSorted] Specify the array is sorted. |
| 5590 * @param {Function|Object|string} [iteratee] The function invoked per itera
tion. |
| 5591 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 5592 * @returns {Array} Returns the new duplicate-value-free array. |
| 5593 * @example |
| 5594 * |
| 5595 * _.uniq([2, 1, 2]); |
| 5596 * // => [2, 1] |
| 5597 * |
| 5598 * // using `isSorted` |
| 5599 * _.uniq([1, 1, 2], true); |
| 5600 * // => [1, 2] |
| 5601 * |
| 5602 * // using an iteratee function |
| 5603 * _.uniq([1, 2.5, 1.5, 2], function(n) { |
| 5604 * return this.floor(n); |
| 5605 * }, Math); |
| 5606 * // => [1, 2.5] |
| 5607 * |
| 5608 * // using the `_.property` callback shorthand |
| 5609 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); |
| 5610 * // => [{ 'x': 1 }, { 'x': 2 }] |
| 5611 */ |
| 5612 function uniq(array, isSorted, iteratee, thisArg) { |
| 5613 var length = array ? array.length : 0; |
| 5614 if (!length) { |
| 5615 return []; |
| 5616 } |
| 5617 if (isSorted != null && typeof isSorted != 'boolean') { |
| 5618 thisArg = iteratee; |
| 5619 iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSort
ed; |
| 5620 isSorted = false; |
| 5621 } |
| 5622 var callback = getCallback(); |
| 5623 if (!(iteratee == null && callback === baseCallback)) { |
| 5624 iteratee = callback(iteratee, thisArg, 3); |
| 5625 } |
| 5626 return (isSorted && getIndexOf() === baseIndexOf) |
| 5627 ? sortedUniq(array, iteratee) |
| 5628 : baseUniq(array, iteratee); |
| 5629 } |
| 5630 |
| 5631 /** |
| 5632 * This method is like `_.zip` except that it accepts an array of grouped |
| 5633 * elements and creates an array regrouping the elements to their pre-zip |
| 5634 * configuration. |
| 5635 * |
| 5636 * @static |
| 5637 * @memberOf _ |
| 5638 * @category Array |
| 5639 * @param {Array} array The array of grouped elements to process. |
| 5640 * @returns {Array} Returns the new array of regrouped elements. |
| 5641 * @example |
| 5642 * |
| 5643 * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); |
| 5644 * // => [['fred', 30, true], ['barney', 40, false]] |
| 5645 * |
| 5646 * _.unzip(zipped); |
| 5647 * // => [['fred', 'barney'], [30, 40], [true, false]] |
| 5648 */ |
| 5649 function unzip(array) { |
| 5650 if (!(array && array.length)) { |
| 5651 return []; |
| 5652 } |
| 5653 var index = -1, |
| 5654 length = 0; |
| 5655 |
| 5656 array = arrayFilter(array, function(group) { |
| 5657 if (isArrayLike(group)) { |
| 5658 length = nativeMax(group.length, length); |
| 5659 return true; |
| 5660 } |
| 5661 }); |
| 5662 var result = Array(length); |
| 5663 while (++index < length) { |
| 5664 result[index] = arrayMap(array, baseProperty(index)); |
| 5665 } |
| 5666 return result; |
| 5667 } |
| 5668 |
| 5669 /** |
| 5670 * This method is like `_.unzip` except that it accepts an iteratee to speci
fy |
| 5671 * how regrouped values should be combined. The `iteratee` is bound to `this
Arg` |
| 5672 * and invoked with four arguments: (accumulator, value, index, group). |
| 5673 * |
| 5674 * @static |
| 5675 * @memberOf _ |
| 5676 * @category Array |
| 5677 * @param {Array} array The array of grouped elements to process. |
| 5678 * @param {Function} [iteratee] The function to combine regrouped values. |
| 5679 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 5680 * @returns {Array} Returns the new array of regrouped elements. |
| 5681 * @example |
| 5682 * |
| 5683 * var zipped = _.zip([1, 2], [10, 20], [100, 200]); |
| 5684 * // => [[1, 10, 100], [2, 20, 200]] |
| 5685 * |
| 5686 * _.unzipWith(zipped, _.add); |
| 5687 * // => [3, 30, 300] |
| 5688 */ |
| 5689 function unzipWith(array, iteratee, thisArg) { |
| 5690 var length = array ? array.length : 0; |
| 5691 if (!length) { |
| 5692 return []; |
| 5693 } |
| 5694 var result = unzip(array); |
| 5695 if (iteratee == null) { |
| 5696 return result; |
| 5697 } |
| 5698 iteratee = bindCallback(iteratee, thisArg, 4); |
| 5699 return arrayMap(result, function(group) { |
| 5700 return arrayReduce(group, iteratee, undefined, true); |
| 5701 }); |
| 5702 } |
| 5703 |
| 5704 /** |
| 5705 * Creates an array excluding all provided values using |
| 5706 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-sameval
uezero) |
| 5707 * for equality comparisons. |
| 5708 * |
| 5709 * @static |
| 5710 * @memberOf _ |
| 5711 * @category Array |
| 5712 * @param {Array} array The array to filter. |
| 5713 * @param {...*} [values] The values to exclude. |
| 5714 * @returns {Array} Returns the new array of filtered values. |
| 5715 * @example |
| 5716 * |
| 5717 * _.without([1, 2, 1, 3], 1, 2); |
| 5718 * // => [3] |
| 5719 */ |
| 5720 var without = restParam(function(array, values) { |
| 5721 return isArrayLike(array) |
| 5722 ? baseDifference(array, values) |
| 5723 : []; |
| 5724 }); |
| 5725 |
| 5726 /** |
| 5727 * Creates an array of unique values that is the [symmetric difference](http
s://en.wikipedia.org/wiki/Symmetric_difference) |
| 5728 * of the provided arrays. |
| 5729 * |
| 5730 * @static |
| 5731 * @memberOf _ |
| 5732 * @category Array |
| 5733 * @param {...Array} [arrays] The arrays to inspect. |
| 5734 * @returns {Array} Returns the new array of values. |
| 5735 * @example |
| 5736 * |
| 5737 * _.xor([1, 2], [4, 2]); |
| 5738 * // => [1, 4] |
| 5739 */ |
| 5740 function xor() { |
| 5741 var index = -1, |
| 5742 length = arguments.length; |
| 5743 |
| 5744 while (++index < length) { |
| 5745 var array = arguments[index]; |
| 5746 if (isArrayLike(array)) { |
| 5747 var result = result |
| 5748 ? arrayPush(baseDifference(result, array), baseDifference(array, res
ult)) |
| 5749 : array; |
| 5750 } |
| 5751 } |
| 5752 return result ? baseUniq(result) : []; |
| 5753 } |
| 5754 |
| 5755 /** |
| 5756 * Creates an array of grouped elements, the first of which contains the fir
st |
| 5757 * elements of the given arrays, the second of which contains the second ele
ments |
| 5758 * of the given arrays, and so on. |
| 5759 * |
| 5760 * @static |
| 5761 * @memberOf _ |
| 5762 * @category Array |
| 5763 * @param {...Array} [arrays] The arrays to process. |
| 5764 * @returns {Array} Returns the new array of grouped elements. |
| 5765 * @example |
| 5766 * |
| 5767 * _.zip(['fred', 'barney'], [30, 40], [true, false]); |
| 5768 * // => [['fred', 30, true], ['barney', 40, false]] |
| 5769 */ |
| 5770 var zip = restParam(unzip); |
| 5771 |
| 5772 /** |
| 5773 * The inverse of `_.pairs`; this method returns an object composed from arr
ays |
| 5774 * of property names and values. Provide either a single two dimensional arr
ay, |
| 5775 * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property na
mes |
| 5776 * and one of corresponding values. |
| 5777 * |
| 5778 * @static |
| 5779 * @memberOf _ |
| 5780 * @alias object |
| 5781 * @category Array |
| 5782 * @param {Array} props The property names. |
| 5783 * @param {Array} [values=[]] The property values. |
| 5784 * @returns {Object} Returns the new object. |
| 5785 * @example |
| 5786 * |
| 5787 * _.zipObject([['fred', 30], ['barney', 40]]); |
| 5788 * // => { 'fred': 30, 'barney': 40 } |
| 5789 * |
| 5790 * _.zipObject(['fred', 'barney'], [30, 40]); |
| 5791 * // => { 'fred': 30, 'barney': 40 } |
| 5792 */ |
| 5793 function zipObject(props, values) { |
| 5794 var index = -1, |
| 5795 length = props ? props.length : 0, |
| 5796 result = {}; |
| 5797 |
| 5798 if (length && !values && !isArray(props[0])) { |
| 5799 values = []; |
| 5800 } |
| 5801 while (++index < length) { |
| 5802 var key = props[index]; |
| 5803 if (values) { |
| 5804 result[key] = values[index]; |
| 5805 } else if (key) { |
| 5806 result[key[0]] = key[1]; |
| 5807 } |
| 5808 } |
| 5809 return result; |
| 5810 } |
| 5811 |
| 5812 /** |
| 5813 * This method is like `_.zip` except that it accepts an iteratee to specify |
| 5814 * how grouped values should be combined. The `iteratee` is bound to `thisAr
g` |
| 5815 * and invoked with four arguments: (accumulator, value, index, group). |
| 5816 * |
| 5817 * @static |
| 5818 * @memberOf _ |
| 5819 * @category Array |
| 5820 * @param {...Array} [arrays] The arrays to process. |
| 5821 * @param {Function} [iteratee] The function to combine grouped values. |
| 5822 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 5823 * @returns {Array} Returns the new array of grouped elements. |
| 5824 * @example |
| 5825 * |
| 5826 * _.zipWith([1, 2], [10, 20], [100, 200], _.add); |
| 5827 * // => [111, 222] |
| 5828 */ |
| 5829 var zipWith = restParam(function(arrays) { |
| 5830 var length = arrays.length, |
| 5831 iteratee = length > 2 ? arrays[length - 2] : undefined, |
| 5832 thisArg = length > 1 ? arrays[length - 1] : undefined; |
| 5833 |
| 5834 if (length > 2 && typeof iteratee == 'function') { |
| 5835 length -= 2; |
| 5836 } else { |
| 5837 iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thi
sArg) : undefined; |
| 5838 thisArg = undefined; |
| 5839 } |
| 5840 arrays.length = length; |
| 5841 return unzipWith(arrays, iteratee, thisArg); |
| 5842 }); |
| 5843 |
| 5844 /*------------------------------------------------------------------------*/ |
| 5845 |
| 5846 /** |
| 5847 * Creates a `lodash` object that wraps `value` with explicit method |
| 5848 * chaining enabled. |
| 5849 * |
| 5850 * @static |
| 5851 * @memberOf _ |
| 5852 * @category Chain |
| 5853 * @param {*} value The value to wrap. |
| 5854 * @returns {Object} Returns the new `lodash` wrapper instance. |
| 5855 * @example |
| 5856 * |
| 5857 * var users = [ |
| 5858 * { 'user': 'barney', 'age': 36 }, |
| 5859 * { 'user': 'fred', 'age': 40 }, |
| 5860 * { 'user': 'pebbles', 'age': 1 } |
| 5861 * ]; |
| 5862 * |
| 5863 * var youngest = _.chain(users) |
| 5864 * .sortBy('age') |
| 5865 * .map(function(chr) { |
| 5866 * return chr.user + ' is ' + chr.age; |
| 5867 * }) |
| 5868 * .first() |
| 5869 * .value(); |
| 5870 * // => 'pebbles is 1' |
| 5871 */ |
| 5872 function chain(value) { |
| 5873 var result = lodash(value); |
| 5874 result.__chain__ = true; |
| 5875 return result; |
| 5876 } |
| 5877 |
| 5878 /** |
| 5879 * This method invokes `interceptor` and returns `value`. The interceptor is |
| 5880 * bound to `thisArg` and invoked with one argument; (value). The purpose of |
| 5881 * this method is to "tap into" a method chain in order to perform operation
s |
| 5882 * on intermediate results within the chain. |
| 5883 * |
| 5884 * @static |
| 5885 * @memberOf _ |
| 5886 * @category Chain |
| 5887 * @param {*} value The value to provide to `interceptor`. |
| 5888 * @param {Function} interceptor The function to invoke. |
| 5889 * @param {*} [thisArg] The `this` binding of `interceptor`. |
| 5890 * @returns {*} Returns `value`. |
| 5891 * @example |
| 5892 * |
| 5893 * _([1, 2, 3]) |
| 5894 * .tap(function(array) { |
| 5895 * array.pop(); |
| 5896 * }) |
| 5897 * .reverse() |
| 5898 * .value(); |
| 5899 * // => [2, 1] |
| 5900 */ |
| 5901 function tap(value, interceptor, thisArg) { |
| 5902 interceptor.call(thisArg, value); |
| 5903 return value; |
| 5904 } |
| 5905 |
| 5906 /** |
| 5907 * This method is like `_.tap` except that it returns the result of `interce
ptor`. |
| 5908 * |
| 5909 * @static |
| 5910 * @memberOf _ |
| 5911 * @category Chain |
| 5912 * @param {*} value The value to provide to `interceptor`. |
| 5913 * @param {Function} interceptor The function to invoke. |
| 5914 * @param {*} [thisArg] The `this` binding of `interceptor`. |
| 5915 * @returns {*} Returns the result of `interceptor`. |
| 5916 * @example |
| 5917 * |
| 5918 * _(' abc ') |
| 5919 * .chain() |
| 5920 * .trim() |
| 5921 * .thru(function(value) { |
| 5922 * return [value]; |
| 5923 * }) |
| 5924 * .value(); |
| 5925 * // => ['abc'] |
| 5926 */ |
| 5927 function thru(value, interceptor, thisArg) { |
| 5928 return interceptor.call(thisArg, value); |
| 5929 } |
| 5930 |
| 5931 /** |
| 5932 * Enables explicit method chaining on the wrapper object. |
| 5933 * |
| 5934 * @name chain |
| 5935 * @memberOf _ |
| 5936 * @category Chain |
| 5937 * @returns {Object} Returns the new `lodash` wrapper instance. |
| 5938 * @example |
| 5939 * |
| 5940 * var users = [ |
| 5941 * { 'user': 'barney', 'age': 36 }, |
| 5942 * { 'user': 'fred', 'age': 40 } |
| 5943 * ]; |
| 5944 * |
| 5945 * // without explicit chaining |
| 5946 * _(users).first(); |
| 5947 * // => { 'user': 'barney', 'age': 36 } |
| 5948 * |
| 5949 * // with explicit chaining |
| 5950 * _(users).chain() |
| 5951 * .first() |
| 5952 * .pick('user') |
| 5953 * .value(); |
| 5954 * // => { 'user': 'barney' } |
| 5955 */ |
| 5956 function wrapperChain() { |
| 5957 return chain(this); |
| 5958 } |
| 5959 |
| 5960 /** |
| 5961 * Executes the chained sequence and returns the wrapped result. |
| 5962 * |
| 5963 * @name commit |
| 5964 * @memberOf _ |
| 5965 * @category Chain |
| 5966 * @returns {Object} Returns the new `lodash` wrapper instance. |
| 5967 * @example |
| 5968 * |
| 5969 * var array = [1, 2]; |
| 5970 * var wrapped = _(array).push(3); |
| 5971 * |
| 5972 * console.log(array); |
| 5973 * // => [1, 2] |
| 5974 * |
| 5975 * wrapped = wrapped.commit(); |
| 5976 * console.log(array); |
| 5977 * // => [1, 2, 3] |
| 5978 * |
| 5979 * wrapped.last(); |
| 5980 * // => 3 |
| 5981 * |
| 5982 * console.log(array); |
| 5983 * // => [1, 2, 3] |
| 5984 */ |
| 5985 function wrapperCommit() { |
| 5986 return new LodashWrapper(this.value(), this.__chain__); |
| 5987 } |
| 5988 |
| 5989 /** |
| 5990 * Creates a new array joining a wrapped array with any additional arrays |
| 5991 * and/or values. |
| 5992 * |
| 5993 * @name concat |
| 5994 * @memberOf _ |
| 5995 * @category Chain |
| 5996 * @param {...*} [values] The values to concatenate. |
| 5997 * @returns {Array} Returns the new concatenated array. |
| 5998 * @example |
| 5999 * |
| 6000 * var array = [1]; |
| 6001 * var wrapped = _(array).concat(2, [3], [[4]]); |
| 6002 * |
| 6003 * console.log(wrapped.value()); |
| 6004 * // => [1, 2, 3, [4]] |
| 6005 * |
| 6006 * console.log(array); |
| 6007 * // => [1] |
| 6008 */ |
| 6009 var wrapperConcat = restParam(function(values) { |
| 6010 values = baseFlatten(values); |
| 6011 return this.thru(function(array) { |
| 6012 return arrayConcat(isArray(array) ? array : [toObject(array)], values); |
| 6013 }); |
| 6014 }); |
| 6015 |
| 6016 /** |
| 6017 * Creates a clone of the chained sequence planting `value` as the wrapped v
alue. |
| 6018 * |
| 6019 * @name plant |
| 6020 * @memberOf _ |
| 6021 * @category Chain |
| 6022 * @returns {Object} Returns the new `lodash` wrapper instance. |
| 6023 * @example |
| 6024 * |
| 6025 * var array = [1, 2]; |
| 6026 * var wrapped = _(array).map(function(value) { |
| 6027 * return Math.pow(value, 2); |
| 6028 * }); |
| 6029 * |
| 6030 * var other = [3, 4]; |
| 6031 * var otherWrapped = wrapped.plant(other); |
| 6032 * |
| 6033 * otherWrapped.value(); |
| 6034 * // => [9, 16] |
| 6035 * |
| 6036 * wrapped.value(); |
| 6037 * // => [1, 4] |
| 6038 */ |
| 6039 function wrapperPlant(value) { |
| 6040 var result, |
| 6041 parent = this; |
| 6042 |
| 6043 while (parent instanceof baseLodash) { |
| 6044 var clone = wrapperClone(parent); |
| 6045 if (result) { |
| 6046 previous.__wrapped__ = clone; |
| 6047 } else { |
| 6048 result = clone; |
| 6049 } |
| 6050 var previous = clone; |
| 6051 parent = parent.__wrapped__; |
| 6052 } |
| 6053 previous.__wrapped__ = value; |
| 6054 return result; |
| 6055 } |
| 6056 |
| 6057 /** |
| 6058 * Reverses the wrapped array so the first element becomes the last, the |
| 6059 * second element becomes the second to last, and so on. |
| 6060 * |
| 6061 * **Note:** This method mutates the wrapped array. |
| 6062 * |
| 6063 * @name reverse |
| 6064 * @memberOf _ |
| 6065 * @category Chain |
| 6066 * @returns {Object} Returns the new reversed `lodash` wrapper instance. |
| 6067 * @example |
| 6068 * |
| 6069 * var array = [1, 2, 3]; |
| 6070 * |
| 6071 * _(array).reverse().value() |
| 6072 * // => [3, 2, 1] |
| 6073 * |
| 6074 * console.log(array); |
| 6075 * // => [3, 2, 1] |
| 6076 */ |
| 6077 function wrapperReverse() { |
| 6078 var value = this.__wrapped__; |
| 6079 |
| 6080 var interceptor = function(value) { |
| 6081 return value.reverse(); |
| 6082 }; |
| 6083 if (value instanceof LazyWrapper) { |
| 6084 var wrapped = value; |
| 6085 if (this.__actions__.length) { |
| 6086 wrapped = new LazyWrapper(this); |
| 6087 } |
| 6088 wrapped = wrapped.reverse(); |
| 6089 wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg
': undefined }); |
| 6090 return new LodashWrapper(wrapped, this.__chain__); |
| 6091 } |
| 6092 return this.thru(interceptor); |
| 6093 } |
| 6094 |
| 6095 /** |
| 6096 * Produces the result of coercing the unwrapped value to a string. |
| 6097 * |
| 6098 * @name toString |
| 6099 * @memberOf _ |
| 6100 * @category Chain |
| 6101 * @returns {string} Returns the coerced string value. |
| 6102 * @example |
| 6103 * |
| 6104 * _([1, 2, 3]).toString(); |
| 6105 * // => '1,2,3' |
| 6106 */ |
| 6107 function wrapperToString() { |
| 6108 return (this.value() + ''); |
| 6109 } |
| 6110 |
| 6111 /** |
| 6112 * Executes the chained sequence to extract the unwrapped value. |
| 6113 * |
| 6114 * @name value |
| 6115 * @memberOf _ |
| 6116 * @alias run, toJSON, valueOf |
| 6117 * @category Chain |
| 6118 * @returns {*} Returns the resolved unwrapped value. |
| 6119 * @example |
| 6120 * |
| 6121 * _([1, 2, 3]).value(); |
| 6122 * // => [1, 2, 3] |
| 6123 */ |
| 6124 function wrapperValue() { |
| 6125 return baseWrapperValue(this.__wrapped__, this.__actions__); |
| 6126 } |
| 6127 |
| 6128 /*------------------------------------------------------------------------*/ |
| 6129 |
| 6130 /** |
| 6131 * Creates an array of elements corresponding to the given keys, or indexes, |
| 6132 * of `collection`. Keys may be specified as individual arguments or as arra
ys |
| 6133 * of keys. |
| 6134 * |
| 6135 * @static |
| 6136 * @memberOf _ |
| 6137 * @category Collection |
| 6138 * @param {Array|Object|string} collection The collection to iterate over. |
| 6139 * @param {...(number|number[]|string|string[])} [props] The property names |
| 6140 * or indexes of elements to pick, specified individually or in arrays. |
| 6141 * @returns {Array} Returns the new array of picked elements. |
| 6142 * @example |
| 6143 * |
| 6144 * _.at(['a', 'b', 'c'], [0, 2]); |
| 6145 * // => ['a', 'c'] |
| 6146 * |
| 6147 * _.at(['barney', 'fred', 'pebbles'], 0, 2); |
| 6148 * // => ['barney', 'pebbles'] |
| 6149 */ |
| 6150 var at = restParam(function(collection, props) { |
| 6151 return baseAt(collection, baseFlatten(props)); |
| 6152 }); |
| 6153 |
| 6154 /** |
| 6155 * Creates an object composed of keys generated from the results of running |
| 6156 * each element of `collection` through `iteratee`. The corresponding value |
| 6157 * of each key is the number of times the key was returned by `iteratee`. |
| 6158 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
| 6159 * (value, index|key, collection). |
| 6160 * |
| 6161 * If a property name is provided for `iteratee` the created `_.property` |
| 6162 * style callback returns the property value of the given element. |
| 6163 * |
| 6164 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6165 * style callback returns `true` for elements that have a matching property |
| 6166 * value, else `false`. |
| 6167 * |
| 6168 * If an object is provided for `iteratee` the created `_.matches` style |
| 6169 * callback returns `true` for elements that have the properties of the give
n |
| 6170 * object, else `false`. |
| 6171 * |
| 6172 * @static |
| 6173 * @memberOf _ |
| 6174 * @category Collection |
| 6175 * @param {Array|Object|string} collection The collection to iterate over. |
| 6176 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 6177 * per iteration. |
| 6178 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6179 * @returns {Object} Returns the composed aggregate object. |
| 6180 * @example |
| 6181 * |
| 6182 * _.countBy([4.3, 6.1, 6.4], function(n) { |
| 6183 * return Math.floor(n); |
| 6184 * }); |
| 6185 * // => { '4': 1, '6': 2 } |
| 6186 * |
| 6187 * _.countBy([4.3, 6.1, 6.4], function(n) { |
| 6188 * return this.floor(n); |
| 6189 * }, Math); |
| 6190 * // => { '4': 1, '6': 2 } |
| 6191 * |
| 6192 * _.countBy(['one', 'two', 'three'], 'length'); |
| 6193 * // => { '3': 2, '5': 1 } |
| 6194 */ |
| 6195 var countBy = createAggregator(function(result, value, key) { |
| 6196 hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); |
| 6197 }); |
| 6198 |
| 6199 /** |
| 6200 * Checks if `predicate` returns truthy for **all** elements of `collection`
. |
| 6201 * The predicate is bound to `thisArg` and invoked with three arguments: |
| 6202 * (value, index|key, collection). |
| 6203 * |
| 6204 * If a property name is provided for `predicate` the created `_.property` |
| 6205 * style callback returns the property value of the given element. |
| 6206 * |
| 6207 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6208 * style callback returns `true` for elements that have a matching property |
| 6209 * value, else `false`. |
| 6210 * |
| 6211 * If an object is provided for `predicate` the created `_.matches` style |
| 6212 * callback returns `true` for elements that have the properties of the give
n |
| 6213 * object, else `false`. |
| 6214 * |
| 6215 * @static |
| 6216 * @memberOf _ |
| 6217 * @alias all |
| 6218 * @category Collection |
| 6219 * @param {Array|Object|string} collection The collection to iterate over. |
| 6220 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 6221 * per iteration. |
| 6222 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 6223 * @returns {boolean} Returns `true` if all elements pass the predicate chec
k, |
| 6224 * else `false`. |
| 6225 * @example |
| 6226 * |
| 6227 * _.every([true, 1, null, 'yes'], Boolean); |
| 6228 * // => false |
| 6229 * |
| 6230 * var users = [ |
| 6231 * { 'user': 'barney', 'active': false }, |
| 6232 * { 'user': 'fred', 'active': false } |
| 6233 * ]; |
| 6234 * |
| 6235 * // using the `_.matches` callback shorthand |
| 6236 * _.every(users, { 'user': 'barney', 'active': false }); |
| 6237 * // => false |
| 6238 * |
| 6239 * // using the `_.matchesProperty` callback shorthand |
| 6240 * _.every(users, 'active', false); |
| 6241 * // => true |
| 6242 * |
| 6243 * // using the `_.property` callback shorthand |
| 6244 * _.every(users, 'active'); |
| 6245 * // => false |
| 6246 */ |
| 6247 function every(collection, predicate, thisArg) { |
| 6248 var func = isArray(collection) ? arrayEvery : baseEvery; |
| 6249 if (thisArg && isIterateeCall(collection, predicate, thisArg)) { |
| 6250 predicate = undefined; |
| 6251 } |
| 6252 if (typeof predicate != 'function' || thisArg !== undefined) { |
| 6253 predicate = getCallback(predicate, thisArg, 3); |
| 6254 } |
| 6255 return func(collection, predicate); |
| 6256 } |
| 6257 |
| 6258 /** |
| 6259 * Iterates over elements of `collection`, returning an array of all element
s |
| 6260 * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
| 6261 * invoked with three arguments: (value, index|key, collection). |
| 6262 * |
| 6263 * If a property name is provided for `predicate` the created `_.property` |
| 6264 * style callback returns the property value of the given element. |
| 6265 * |
| 6266 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6267 * style callback returns `true` for elements that have a matching property |
| 6268 * value, else `false`. |
| 6269 * |
| 6270 * If an object is provided for `predicate` the created `_.matches` style |
| 6271 * callback returns `true` for elements that have the properties of the give
n |
| 6272 * object, else `false`. |
| 6273 * |
| 6274 * @static |
| 6275 * @memberOf _ |
| 6276 * @alias select |
| 6277 * @category Collection |
| 6278 * @param {Array|Object|string} collection The collection to iterate over. |
| 6279 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 6280 * per iteration. |
| 6281 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 6282 * @returns {Array} Returns the new filtered array. |
| 6283 * @example |
| 6284 * |
| 6285 * _.filter([4, 5, 6], function(n) { |
| 6286 * return n % 2 == 0; |
| 6287 * }); |
| 6288 * // => [4, 6] |
| 6289 * |
| 6290 * var users = [ |
| 6291 * { 'user': 'barney', 'age': 36, 'active': true }, |
| 6292 * { 'user': 'fred', 'age': 40, 'active': false } |
| 6293 * ]; |
| 6294 * |
| 6295 * // using the `_.matches` callback shorthand |
| 6296 * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); |
| 6297 * // => ['barney'] |
| 6298 * |
| 6299 * // using the `_.matchesProperty` callback shorthand |
| 6300 * _.pluck(_.filter(users, 'active', false), 'user'); |
| 6301 * // => ['fred'] |
| 6302 * |
| 6303 * // using the `_.property` callback shorthand |
| 6304 * _.pluck(_.filter(users, 'active'), 'user'); |
| 6305 * // => ['barney'] |
| 6306 */ |
| 6307 function filter(collection, predicate, thisArg) { |
| 6308 var func = isArray(collection) ? arrayFilter : baseFilter; |
| 6309 predicate = getCallback(predicate, thisArg, 3); |
| 6310 return func(collection, predicate); |
| 6311 } |
| 6312 |
| 6313 /** |
| 6314 * Iterates over elements of `collection`, returning the first element |
| 6315 * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
| 6316 * invoked with three arguments: (value, index|key, collection). |
| 6317 * |
| 6318 * If a property name is provided for `predicate` the created `_.property` |
| 6319 * style callback returns the property value of the given element. |
| 6320 * |
| 6321 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6322 * style callback returns `true` for elements that have a matching property |
| 6323 * value, else `false`. |
| 6324 * |
| 6325 * If an object is provided for `predicate` the created `_.matches` style |
| 6326 * callback returns `true` for elements that have the properties of the give
n |
| 6327 * object, else `false`. |
| 6328 * |
| 6329 * @static |
| 6330 * @memberOf _ |
| 6331 * @alias detect |
| 6332 * @category Collection |
| 6333 * @param {Array|Object|string} collection The collection to search. |
| 6334 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 6335 * per iteration. |
| 6336 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 6337 * @returns {*} Returns the matched element, else `undefined`. |
| 6338 * @example |
| 6339 * |
| 6340 * var users = [ |
| 6341 * { 'user': 'barney', 'age': 36, 'active': true }, |
| 6342 * { 'user': 'fred', 'age': 40, 'active': false }, |
| 6343 * { 'user': 'pebbles', 'age': 1, 'active': true } |
| 6344 * ]; |
| 6345 * |
| 6346 * _.result(_.find(users, function(chr) { |
| 6347 * return chr.age < 40; |
| 6348 * }), 'user'); |
| 6349 * // => 'barney' |
| 6350 * |
| 6351 * // using the `_.matches` callback shorthand |
| 6352 * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); |
| 6353 * // => 'pebbles' |
| 6354 * |
| 6355 * // using the `_.matchesProperty` callback shorthand |
| 6356 * _.result(_.find(users, 'active', false), 'user'); |
| 6357 * // => 'fred' |
| 6358 * |
| 6359 * // using the `_.property` callback shorthand |
| 6360 * _.result(_.find(users, 'active'), 'user'); |
| 6361 * // => 'barney' |
| 6362 */ |
| 6363 var find = createFind(baseEach); |
| 6364 |
| 6365 /** |
| 6366 * This method is like `_.find` except that it iterates over elements of |
| 6367 * `collection` from right to left. |
| 6368 * |
| 6369 * @static |
| 6370 * @memberOf _ |
| 6371 * @category Collection |
| 6372 * @param {Array|Object|string} collection The collection to search. |
| 6373 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 6374 * per iteration. |
| 6375 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 6376 * @returns {*} Returns the matched element, else `undefined`. |
| 6377 * @example |
| 6378 * |
| 6379 * _.findLast([1, 2, 3, 4], function(n) { |
| 6380 * return n % 2 == 1; |
| 6381 * }); |
| 6382 * // => 3 |
| 6383 */ |
| 6384 var findLast = createFind(baseEachRight, true); |
| 6385 |
| 6386 /** |
| 6387 * Performs a deep comparison between each element in `collection` and the |
| 6388 * source object, returning the first element that has equivalent property |
| 6389 * values. |
| 6390 * |
| 6391 * **Note:** This method supports comparing arrays, booleans, `Date` objects
, |
| 6392 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
| 6393 * their own, not inherited, enumerable properties. For comparing a single |
| 6394 * own or inherited property value see `_.matchesProperty`. |
| 6395 * |
| 6396 * @static |
| 6397 * @memberOf _ |
| 6398 * @category Collection |
| 6399 * @param {Array|Object|string} collection The collection to search. |
| 6400 * @param {Object} source The object of property values to match. |
| 6401 * @returns {*} Returns the matched element, else `undefined`. |
| 6402 * @example |
| 6403 * |
| 6404 * var users = [ |
| 6405 * { 'user': 'barney', 'age': 36, 'active': true }, |
| 6406 * { 'user': 'fred', 'age': 40, 'active': false } |
| 6407 * ]; |
| 6408 * |
| 6409 * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); |
| 6410 * // => 'barney' |
| 6411 * |
| 6412 * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); |
| 6413 * // => 'fred' |
| 6414 */ |
| 6415 function findWhere(collection, source) { |
| 6416 return find(collection, baseMatches(source)); |
| 6417 } |
| 6418 |
| 6419 /** |
| 6420 * Iterates over elements of `collection` invoking `iteratee` for each eleme
nt. |
| 6421 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
| 6422 * (value, index|key, collection). Iteratee functions may exit iteration ear
ly |
| 6423 * by explicitly returning `false`. |
| 6424 * |
| 6425 * **Note:** As with other "Collections" methods, objects with a "length" pr
operty |
| 6426 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
| 6427 * may be used for object iteration. |
| 6428 * |
| 6429 * @static |
| 6430 * @memberOf _ |
| 6431 * @alias each |
| 6432 * @category Collection |
| 6433 * @param {Array|Object|string} collection The collection to iterate over. |
| 6434 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 6435 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6436 * @returns {Array|Object|string} Returns `collection`. |
| 6437 * @example |
| 6438 * |
| 6439 * _([1, 2]).forEach(function(n) { |
| 6440 * console.log(n); |
| 6441 * }).value(); |
| 6442 * // => logs each value from left to right and returns the array |
| 6443 * |
| 6444 * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { |
| 6445 * console.log(n, key); |
| 6446 * }); |
| 6447 * // => logs each value-key pair and returns the object (iteration order is
not guaranteed) |
| 6448 */ |
| 6449 var forEach = createForEach(arrayEach, baseEach); |
| 6450 |
| 6451 /** |
| 6452 * This method is like `_.forEach` except that it iterates over elements of |
| 6453 * `collection` from right to left. |
| 6454 * |
| 6455 * @static |
| 6456 * @memberOf _ |
| 6457 * @alias eachRight |
| 6458 * @category Collection |
| 6459 * @param {Array|Object|string} collection The collection to iterate over. |
| 6460 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 6461 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6462 * @returns {Array|Object|string} Returns `collection`. |
| 6463 * @example |
| 6464 * |
| 6465 * _([1, 2]).forEachRight(function(n) { |
| 6466 * console.log(n); |
| 6467 * }).value(); |
| 6468 * // => logs each value from right to left and returns the array |
| 6469 */ |
| 6470 var forEachRight = createForEach(arrayEachRight, baseEachRight); |
| 6471 |
| 6472 /** |
| 6473 * Creates an object composed of keys generated from the results of running |
| 6474 * each element of `collection` through `iteratee`. The corresponding value |
| 6475 * of each key is an array of the elements responsible for generating the ke
y. |
| 6476 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
| 6477 * (value, index|key, collection). |
| 6478 * |
| 6479 * If a property name is provided for `iteratee` the created `_.property` |
| 6480 * style callback returns the property value of the given element. |
| 6481 * |
| 6482 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6483 * style callback returns `true` for elements that have a matching property |
| 6484 * value, else `false`. |
| 6485 * |
| 6486 * If an object is provided for `iteratee` the created `_.matches` style |
| 6487 * callback returns `true` for elements that have the properties of the give
n |
| 6488 * object, else `false`. |
| 6489 * |
| 6490 * @static |
| 6491 * @memberOf _ |
| 6492 * @category Collection |
| 6493 * @param {Array|Object|string} collection The collection to iterate over. |
| 6494 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 6495 * per iteration. |
| 6496 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6497 * @returns {Object} Returns the composed aggregate object. |
| 6498 * @example |
| 6499 * |
| 6500 * _.groupBy([4.2, 6.1, 6.4], function(n) { |
| 6501 * return Math.floor(n); |
| 6502 * }); |
| 6503 * // => { '4': [4.2], '6': [6.1, 6.4] } |
| 6504 * |
| 6505 * _.groupBy([4.2, 6.1, 6.4], function(n) { |
| 6506 * return this.floor(n); |
| 6507 * }, Math); |
| 6508 * // => { '4': [4.2], '6': [6.1, 6.4] } |
| 6509 * |
| 6510 * // using the `_.property` callback shorthand |
| 6511 * _.groupBy(['one', 'two', 'three'], 'length'); |
| 6512 * // => { '3': ['one', 'two'], '5': ['three'] } |
| 6513 */ |
| 6514 var groupBy = createAggregator(function(result, value, key) { |
| 6515 if (hasOwnProperty.call(result, key)) { |
| 6516 result[key].push(value); |
| 6517 } else { |
| 6518 result[key] = [value]; |
| 6519 } |
| 6520 }); |
| 6521 |
| 6522 /** |
| 6523 * Checks if `target` is in `collection` using |
| 6524 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-sameval
uezero) |
| 6525 * for equality comparisons. If `fromIndex` is negative, it's used as the of
fset |
| 6526 * from the end of `collection`. |
| 6527 * |
| 6528 * @static |
| 6529 * @memberOf _ |
| 6530 * @alias contains, include |
| 6531 * @category Collection |
| 6532 * @param {Array|Object|string} collection The collection to search. |
| 6533 * @param {*} target The value to search for. |
| 6534 * @param {number} [fromIndex=0] The index to search from. |
| 6535 * @param- {Object} [guard] Enables use as a callback for functions like `_.
reduce`. |
| 6536 * @returns {boolean} Returns `true` if a matching element is found, else `f
alse`. |
| 6537 * @example |
| 6538 * |
| 6539 * _.includes([1, 2, 3], 1); |
| 6540 * // => true |
| 6541 * |
| 6542 * _.includes([1, 2, 3], 1, 2); |
| 6543 * // => false |
| 6544 * |
| 6545 * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); |
| 6546 * // => true |
| 6547 * |
| 6548 * _.includes('pebbles', 'eb'); |
| 6549 * // => true |
| 6550 */ |
| 6551 function includes(collection, target, fromIndex, guard) { |
| 6552 var length = collection ? getLength(collection) : 0; |
| 6553 if (!isLength(length)) { |
| 6554 collection = values(collection); |
| 6555 length = collection.length; |
| 6556 } |
| 6557 if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromI
ndex, guard))) { |
| 6558 fromIndex = 0; |
| 6559 } else { |
| 6560 fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromInde
x || 0); |
| 6561 } |
| 6562 return (typeof collection == 'string' || !isArray(collection) && isString(
collection)) |
| 6563 ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) |
| 6564 : (!!length && getIndexOf(collection, target, fromIndex) > -1); |
| 6565 } |
| 6566 |
| 6567 /** |
| 6568 * Creates an object composed of keys generated from the results of running |
| 6569 * each element of `collection` through `iteratee`. The corresponding value |
| 6570 * of each key is the last element responsible for generating the key. The |
| 6571 * iteratee function is bound to `thisArg` and invoked with three arguments: |
| 6572 * (value, index|key, collection). |
| 6573 * |
| 6574 * If a property name is provided for `iteratee` the created `_.property` |
| 6575 * style callback returns the property value of the given element. |
| 6576 * |
| 6577 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6578 * style callback returns `true` for elements that have a matching property |
| 6579 * value, else `false`. |
| 6580 * |
| 6581 * If an object is provided for `iteratee` the created `_.matches` style |
| 6582 * callback returns `true` for elements that have the properties of the give
n |
| 6583 * object, else `false`. |
| 6584 * |
| 6585 * @static |
| 6586 * @memberOf _ |
| 6587 * @category Collection |
| 6588 * @param {Array|Object|string} collection The collection to iterate over. |
| 6589 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 6590 * per iteration. |
| 6591 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6592 * @returns {Object} Returns the composed aggregate object. |
| 6593 * @example |
| 6594 * |
| 6595 * var keyData = [ |
| 6596 * { 'dir': 'left', 'code': 97 }, |
| 6597 * { 'dir': 'right', 'code': 100 } |
| 6598 * ]; |
| 6599 * |
| 6600 * _.indexBy(keyData, 'dir'); |
| 6601 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right',
'code': 100 } } |
| 6602 * |
| 6603 * _.indexBy(keyData, function(object) { |
| 6604 * return String.fromCharCode(object.code); |
| 6605 * }); |
| 6606 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code'
: 100 } } |
| 6607 * |
| 6608 * _.indexBy(keyData, function(object) { |
| 6609 * return this.fromCharCode(object.code); |
| 6610 * }, String); |
| 6611 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code'
: 100 } } |
| 6612 */ |
| 6613 var indexBy = createAggregator(function(result, value, key) { |
| 6614 result[key] = value; |
| 6615 }); |
| 6616 |
| 6617 /** |
| 6618 * Invokes the method at `path` of each element in `collection`, returning |
| 6619 * an array of the results of each invoked method. Any additional arguments |
| 6620 * are provided to each invoked method. If `methodName` is a function it's |
| 6621 * invoked for, and `this` bound to, each element in `collection`. |
| 6622 * |
| 6623 * @static |
| 6624 * @memberOf _ |
| 6625 * @category Collection |
| 6626 * @param {Array|Object|string} collection The collection to iterate over. |
| 6627 * @param {Array|Function|string} path The path of the method to invoke or |
| 6628 * the function invoked per iteration. |
| 6629 * @param {...*} [args] The arguments to invoke the method with. |
| 6630 * @returns {Array} Returns the array of results. |
| 6631 * @example |
| 6632 * |
| 6633 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); |
| 6634 * // => [[1, 5, 7], [1, 2, 3]] |
| 6635 * |
| 6636 * _.invoke([123, 456], String.prototype.split, ''); |
| 6637 * // => [['1', '2', '3'], ['4', '5', '6']] |
| 6638 */ |
| 6639 var invoke = restParam(function(collection, path, args) { |
| 6640 var index = -1, |
| 6641 isFunc = typeof path == 'function', |
| 6642 isProp = isKey(path), |
| 6643 result = isArrayLike(collection) ? Array(collection.length) : []; |
| 6644 |
| 6645 baseEach(collection, function(value) { |
| 6646 var func = isFunc ? path : ((isProp && value != null) ? value[path] : un
defined); |
| 6647 result[++index] = func ? func.apply(value, args) : invokePath(value, pat
h, args); |
| 6648 }); |
| 6649 return result; |
| 6650 }); |
| 6651 |
| 6652 /** |
| 6653 * Creates an array of values by running each element in `collection` throug
h |
| 6654 * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three |
| 6655 * arguments: (value, index|key, collection). |
| 6656 * |
| 6657 * If a property name is provided for `iteratee` the created `_.property` |
| 6658 * style callback returns the property value of the given element. |
| 6659 * |
| 6660 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6661 * style callback returns `true` for elements that have a matching property |
| 6662 * value, else `false`. |
| 6663 * |
| 6664 * If an object is provided for `iteratee` the created `_.matches` style |
| 6665 * callback returns `true` for elements that have the properties of the give
n |
| 6666 * object, else `false`. |
| 6667 * |
| 6668 * Many lodash methods are guarded to work as iteratees for methods like |
| 6669 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. |
| 6670 * |
| 6671 * The guarded methods are: |
| 6672 * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, |
| 6673 * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, |
| 6674 * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, |
| 6675 * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, |
| 6676 * `sum`, `uniq`, and `words` |
| 6677 * |
| 6678 * @static |
| 6679 * @memberOf _ |
| 6680 * @alias collect |
| 6681 * @category Collection |
| 6682 * @param {Array|Object|string} collection The collection to iterate over. |
| 6683 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 6684 * per iteration. |
| 6685 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6686 * @returns {Array} Returns the new mapped array. |
| 6687 * @example |
| 6688 * |
| 6689 * function timesThree(n) { |
| 6690 * return n * 3; |
| 6691 * } |
| 6692 * |
| 6693 * _.map([1, 2], timesThree); |
| 6694 * // => [3, 6] |
| 6695 * |
| 6696 * _.map({ 'a': 1, 'b': 2 }, timesThree); |
| 6697 * // => [3, 6] (iteration order is not guaranteed) |
| 6698 * |
| 6699 * var users = [ |
| 6700 * { 'user': 'barney' }, |
| 6701 * { 'user': 'fred' } |
| 6702 * ]; |
| 6703 * |
| 6704 * // using the `_.property` callback shorthand |
| 6705 * _.map(users, 'user'); |
| 6706 * // => ['barney', 'fred'] |
| 6707 */ |
| 6708 function map(collection, iteratee, thisArg) { |
| 6709 var func = isArray(collection) ? arrayMap : baseMap; |
| 6710 iteratee = getCallback(iteratee, thisArg, 3); |
| 6711 return func(collection, iteratee); |
| 6712 } |
| 6713 |
| 6714 /** |
| 6715 * Creates an array of elements split into two groups, the first of which |
| 6716 * contains elements `predicate` returns truthy for, while the second of whi
ch |
| 6717 * contains elements `predicate` returns falsey for. The predicate is bound |
| 6718 * to `thisArg` and invoked with three arguments: (value, index|key, collect
ion). |
| 6719 * |
| 6720 * If a property name is provided for `predicate` the created `_.property` |
| 6721 * style callback returns the property value of the given element. |
| 6722 * |
| 6723 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 6724 * style callback returns `true` for elements that have a matching property |
| 6725 * value, else `false`. |
| 6726 * |
| 6727 * If an object is provided for `predicate` the created `_.matches` style |
| 6728 * callback returns `true` for elements that have the properties of the give
n |
| 6729 * object, else `false`. |
| 6730 * |
| 6731 * @static |
| 6732 * @memberOf _ |
| 6733 * @category Collection |
| 6734 * @param {Array|Object|string} collection The collection to iterate over. |
| 6735 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 6736 * per iteration. |
| 6737 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 6738 * @returns {Array} Returns the array of grouped elements. |
| 6739 * @example |
| 6740 * |
| 6741 * _.partition([1, 2, 3], function(n) { |
| 6742 * return n % 2; |
| 6743 * }); |
| 6744 * // => [[1, 3], [2]] |
| 6745 * |
| 6746 * _.partition([1.2, 2.3, 3.4], function(n) { |
| 6747 * return this.floor(n) % 2; |
| 6748 * }, Math); |
| 6749 * // => [[1.2, 3.4], [2.3]] |
| 6750 * |
| 6751 * var users = [ |
| 6752 * { 'user': 'barney', 'age': 36, 'active': false }, |
| 6753 * { 'user': 'fred', 'age': 40, 'active': true }, |
| 6754 * { 'user': 'pebbles', 'age': 1, 'active': false } |
| 6755 * ]; |
| 6756 * |
| 6757 * var mapper = function(array) { |
| 6758 * return _.pluck(array, 'user'); |
| 6759 * }; |
| 6760 * |
| 6761 * // using the `_.matches` callback shorthand |
| 6762 * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); |
| 6763 * // => [['pebbles'], ['barney', 'fred']] |
| 6764 * |
| 6765 * // using the `_.matchesProperty` callback shorthand |
| 6766 * _.map(_.partition(users, 'active', false), mapper); |
| 6767 * // => [['barney', 'pebbles'], ['fred']] |
| 6768 * |
| 6769 * // using the `_.property` callback shorthand |
| 6770 * _.map(_.partition(users, 'active'), mapper); |
| 6771 * // => [['fred'], ['barney', 'pebbles']] |
| 6772 */ |
| 6773 var partition = createAggregator(function(result, value, key) { |
| 6774 result[key ? 0 : 1].push(value); |
| 6775 }, function() { return [[], []]; }); |
| 6776 |
| 6777 /** |
| 6778 * Gets the property value of `path` from all elements in `collection`. |
| 6779 * |
| 6780 * @static |
| 6781 * @memberOf _ |
| 6782 * @category Collection |
| 6783 * @param {Array|Object|string} collection The collection to iterate over. |
| 6784 * @param {Array|string} path The path of the property to pluck. |
| 6785 * @returns {Array} Returns the property values. |
| 6786 * @example |
| 6787 * |
| 6788 * var users = [ |
| 6789 * { 'user': 'barney', 'age': 36 }, |
| 6790 * { 'user': 'fred', 'age': 40 } |
| 6791 * ]; |
| 6792 * |
| 6793 * _.pluck(users, 'user'); |
| 6794 * // => ['barney', 'fred'] |
| 6795 * |
| 6796 * var userIndex = _.indexBy(users, 'user'); |
| 6797 * _.pluck(userIndex, 'age'); |
| 6798 * // => [36, 40] (iteration order is not guaranteed) |
| 6799 */ |
| 6800 function pluck(collection, path) { |
| 6801 return map(collection, property(path)); |
| 6802 } |
| 6803 |
| 6804 /** |
| 6805 * Reduces `collection` to a value which is the accumulated result of runnin
g |
| 6806 * each element in `collection` through `iteratee`, where each successive |
| 6807 * invocation is supplied the return value of the previous. If `accumulator` |
| 6808 * is not provided the first element of `collection` is used as the initial |
| 6809 * value. The `iteratee` is bound to `thisArg` and invoked with four argumen
ts: |
| 6810 * (accumulator, value, index|key, collection). |
| 6811 * |
| 6812 * Many lodash methods are guarded to work as iteratees for methods like |
| 6813 * `_.reduce`, `_.reduceRight`, and `_.transform`. |
| 6814 * |
| 6815 * The guarded methods are: |
| 6816 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, |
| 6817 * and `sortByOrder` |
| 6818 * |
| 6819 * @static |
| 6820 * @memberOf _ |
| 6821 * @alias foldl, inject |
| 6822 * @category Collection |
| 6823 * @param {Array|Object|string} collection The collection to iterate over. |
| 6824 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 6825 * @param {*} [accumulator] The initial value. |
| 6826 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6827 * @returns {*} Returns the accumulated value. |
| 6828 * @example |
| 6829 * |
| 6830 * _.reduce([1, 2], function(total, n) { |
| 6831 * return total + n; |
| 6832 * }); |
| 6833 * // => 3 |
| 6834 * |
| 6835 * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { |
| 6836 * result[key] = n * 3; |
| 6837 * return result; |
| 6838 * }, {}); |
| 6839 * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) |
| 6840 */ |
| 6841 var reduce = createReduce(arrayReduce, baseEach); |
| 6842 |
| 6843 /** |
| 6844 * This method is like `_.reduce` except that it iterates over elements of |
| 6845 * `collection` from right to left. |
| 6846 * |
| 6847 * @static |
| 6848 * @memberOf _ |
| 6849 * @alias foldr |
| 6850 * @category Collection |
| 6851 * @param {Array|Object|string} collection The collection to iterate over. |
| 6852 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 6853 * @param {*} [accumulator] The initial value. |
| 6854 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 6855 * @returns {*} Returns the accumulated value. |
| 6856 * @example |
| 6857 * |
| 6858 * var array = [[0, 1], [2, 3], [4, 5]]; |
| 6859 * |
| 6860 * _.reduceRight(array, function(flattened, other) { |
| 6861 * return flattened.concat(other); |
| 6862 * }, []); |
| 6863 * // => [4, 5, 2, 3, 0, 1] |
| 6864 */ |
| 6865 var reduceRight = createReduce(arrayReduceRight, baseEachRight); |
| 6866 |
| 6867 /** |
| 6868 * The opposite of `_.filter`; this method returns the elements of `collecti
on` |
| 6869 * that `predicate` does **not** return truthy for. |
| 6870 * |
| 6871 * @static |
| 6872 * @memberOf _ |
| 6873 * @category Collection |
| 6874 * @param {Array|Object|string} collection The collection to iterate over. |
| 6875 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 6876 * per iteration. |
| 6877 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 6878 * @returns {Array} Returns the new filtered array. |
| 6879 * @example |
| 6880 * |
| 6881 * _.reject([1, 2, 3, 4], function(n) { |
| 6882 * return n % 2 == 0; |
| 6883 * }); |
| 6884 * // => [1, 3] |
| 6885 * |
| 6886 * var users = [ |
| 6887 * { 'user': 'barney', 'age': 36, 'active': false }, |
| 6888 * { 'user': 'fred', 'age': 40, 'active': true } |
| 6889 * ]; |
| 6890 * |
| 6891 * // using the `_.matches` callback shorthand |
| 6892 * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); |
| 6893 * // => ['barney'] |
| 6894 * |
| 6895 * // using the `_.matchesProperty` callback shorthand |
| 6896 * _.pluck(_.reject(users, 'active', false), 'user'); |
| 6897 * // => ['fred'] |
| 6898 * |
| 6899 * // using the `_.property` callback shorthand |
| 6900 * _.pluck(_.reject(users, 'active'), 'user'); |
| 6901 * // => ['barney'] |
| 6902 */ |
| 6903 function reject(collection, predicate, thisArg) { |
| 6904 var func = isArray(collection) ? arrayFilter : baseFilter; |
| 6905 predicate = getCallback(predicate, thisArg, 3); |
| 6906 return func(collection, function(value, index, collection) { |
| 6907 return !predicate(value, index, collection); |
| 6908 }); |
| 6909 } |
| 6910 |
| 6911 /** |
| 6912 * Gets a random element or `n` random elements from a collection. |
| 6913 * |
| 6914 * @static |
| 6915 * @memberOf _ |
| 6916 * @category Collection |
| 6917 * @param {Array|Object|string} collection The collection to sample. |
| 6918 * @param {number} [n] The number of elements to sample. |
| 6919 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 6920 * @returns {*} Returns the random sample(s). |
| 6921 * @example |
| 6922 * |
| 6923 * _.sample([1, 2, 3, 4]); |
| 6924 * // => 2 |
| 6925 * |
| 6926 * _.sample([1, 2, 3, 4], 2); |
| 6927 * // => [3, 1] |
| 6928 */ |
| 6929 function sample(collection, n, guard) { |
| 6930 if (guard ? isIterateeCall(collection, n, guard) : n == null) { |
| 6931 collection = toIterable(collection); |
| 6932 var length = collection.length; |
| 6933 return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; |
| 6934 } |
| 6935 var index = -1, |
| 6936 result = toArray(collection), |
| 6937 length = result.length, |
| 6938 lastIndex = length - 1; |
| 6939 |
| 6940 n = nativeMin(n < 0 ? 0 : (+n || 0), length); |
| 6941 while (++index < n) { |
| 6942 var rand = baseRandom(index, lastIndex), |
| 6943 value = result[rand]; |
| 6944 |
| 6945 result[rand] = result[index]; |
| 6946 result[index] = value; |
| 6947 } |
| 6948 result.length = n; |
| 6949 return result; |
| 6950 } |
| 6951 |
| 6952 /** |
| 6953 * Creates an array of shuffled values, using a version of the |
| 6954 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle
). |
| 6955 * |
| 6956 * @static |
| 6957 * @memberOf _ |
| 6958 * @category Collection |
| 6959 * @param {Array|Object|string} collection The collection to shuffle. |
| 6960 * @returns {Array} Returns the new shuffled array. |
| 6961 * @example |
| 6962 * |
| 6963 * _.shuffle([1, 2, 3, 4]); |
| 6964 * // => [4, 1, 3, 2] |
| 6965 */ |
| 6966 function shuffle(collection) { |
| 6967 return sample(collection, POSITIVE_INFINITY); |
| 6968 } |
| 6969 |
| 6970 /** |
| 6971 * Gets the size of `collection` by returning its length for array-like |
| 6972 * values or the number of own enumerable properties for objects. |
| 6973 * |
| 6974 * @static |
| 6975 * @memberOf _ |
| 6976 * @category Collection |
| 6977 * @param {Array|Object|string} collection The collection to inspect. |
| 6978 * @returns {number} Returns the size of `collection`. |
| 6979 * @example |
| 6980 * |
| 6981 * _.size([1, 2, 3]); |
| 6982 * // => 3 |
| 6983 * |
| 6984 * _.size({ 'a': 1, 'b': 2 }); |
| 6985 * // => 2 |
| 6986 * |
| 6987 * _.size('pebbles'); |
| 6988 * // => 7 |
| 6989 */ |
| 6990 function size(collection) { |
| 6991 var length = collection ? getLength(collection) : 0; |
| 6992 return isLength(length) ? length : keys(collection).length; |
| 6993 } |
| 6994 |
| 6995 /** |
| 6996 * Checks if `predicate` returns truthy for **any** element of `collection`. |
| 6997 * The function returns as soon as it finds a passing value and does not ite
rate |
| 6998 * over the entire collection. The predicate is bound to `thisArg` and invok
ed |
| 6999 * with three arguments: (value, index|key, collection). |
| 7000 * |
| 7001 * If a property name is provided for `predicate` the created `_.property` |
| 7002 * style callback returns the property value of the given element. |
| 7003 * |
| 7004 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 7005 * style callback returns `true` for elements that have a matching property |
| 7006 * value, else `false`. |
| 7007 * |
| 7008 * If an object is provided for `predicate` the created `_.matches` style |
| 7009 * callback returns `true` for elements that have the properties of the give
n |
| 7010 * object, else `false`. |
| 7011 * |
| 7012 * @static |
| 7013 * @memberOf _ |
| 7014 * @alias any |
| 7015 * @category Collection |
| 7016 * @param {Array|Object|string} collection The collection to iterate over. |
| 7017 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 7018 * per iteration. |
| 7019 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 7020 * @returns {boolean} Returns `true` if any element passes the predicate che
ck, |
| 7021 * else `false`. |
| 7022 * @example |
| 7023 * |
| 7024 * _.some([null, 0, 'yes', false], Boolean); |
| 7025 * // => true |
| 7026 * |
| 7027 * var users = [ |
| 7028 * { 'user': 'barney', 'active': true }, |
| 7029 * { 'user': 'fred', 'active': false } |
| 7030 * ]; |
| 7031 * |
| 7032 * // using the `_.matches` callback shorthand |
| 7033 * _.some(users, { 'user': 'barney', 'active': false }); |
| 7034 * // => false |
| 7035 * |
| 7036 * // using the `_.matchesProperty` callback shorthand |
| 7037 * _.some(users, 'active', false); |
| 7038 * // => true |
| 7039 * |
| 7040 * // using the `_.property` callback shorthand |
| 7041 * _.some(users, 'active'); |
| 7042 * // => true |
| 7043 */ |
| 7044 function some(collection, predicate, thisArg) { |
| 7045 var func = isArray(collection) ? arraySome : baseSome; |
| 7046 if (thisArg && isIterateeCall(collection, predicate, thisArg)) { |
| 7047 predicate = undefined; |
| 7048 } |
| 7049 if (typeof predicate != 'function' || thisArg !== undefined) { |
| 7050 predicate = getCallback(predicate, thisArg, 3); |
| 7051 } |
| 7052 return func(collection, predicate); |
| 7053 } |
| 7054 |
| 7055 /** |
| 7056 * Creates an array of elements, sorted in ascending order by the results of |
| 7057 * running each element in a collection through `iteratee`. This method perf
orms |
| 7058 * a stable sort, that is, it preserves the original sort order of equal ele
ments. |
| 7059 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
| 7060 * (value, index|key, collection). |
| 7061 * |
| 7062 * If a property name is provided for `iteratee` the created `_.property` |
| 7063 * style callback returns the property value of the given element. |
| 7064 * |
| 7065 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 7066 * style callback returns `true` for elements that have a matching property |
| 7067 * value, else `false`. |
| 7068 * |
| 7069 * If an object is provided for `iteratee` the created `_.matches` style |
| 7070 * callback returns `true` for elements that have the properties of the give
n |
| 7071 * object, else `false`. |
| 7072 * |
| 7073 * @static |
| 7074 * @memberOf _ |
| 7075 * @category Collection |
| 7076 * @param {Array|Object|string} collection The collection to iterate over. |
| 7077 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 7078 * per iteration. |
| 7079 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 7080 * @returns {Array} Returns the new sorted array. |
| 7081 * @example |
| 7082 * |
| 7083 * _.sortBy([1, 2, 3], function(n) { |
| 7084 * return Math.sin(n); |
| 7085 * }); |
| 7086 * // => [3, 1, 2] |
| 7087 * |
| 7088 * _.sortBy([1, 2, 3], function(n) { |
| 7089 * return this.sin(n); |
| 7090 * }, Math); |
| 7091 * // => [3, 1, 2] |
| 7092 * |
| 7093 * var users = [ |
| 7094 * { 'user': 'fred' }, |
| 7095 * { 'user': 'pebbles' }, |
| 7096 * { 'user': 'barney' } |
| 7097 * ]; |
| 7098 * |
| 7099 * // using the `_.property` callback shorthand |
| 7100 * _.pluck(_.sortBy(users, 'user'), 'user'); |
| 7101 * // => ['barney', 'fred', 'pebbles'] |
| 7102 */ |
| 7103 function sortBy(collection, iteratee, thisArg) { |
| 7104 if (collection == null) { |
| 7105 return []; |
| 7106 } |
| 7107 if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
| 7108 iteratee = undefined; |
| 7109 } |
| 7110 var index = -1; |
| 7111 iteratee = getCallback(iteratee, thisArg, 3); |
| 7112 |
| 7113 var result = baseMap(collection, function(value, key, collection) { |
| 7114 return { 'criteria': iteratee(value, key, collection), 'index': ++index,
'value': value }; |
| 7115 }); |
| 7116 return baseSortBy(result, compareAscending); |
| 7117 } |
| 7118 |
| 7119 /** |
| 7120 * This method is like `_.sortBy` except that it can sort by multiple iterat
ees |
| 7121 * or property names. |
| 7122 * |
| 7123 * If a property name is provided for an iteratee the created `_.property` |
| 7124 * style callback returns the property value of the given element. |
| 7125 * |
| 7126 * If an object is provided for an iteratee the created `_.matches` style |
| 7127 * callback returns `true` for elements that have the properties of the give
n |
| 7128 * object, else `false`. |
| 7129 * |
| 7130 * @static |
| 7131 * @memberOf _ |
| 7132 * @category Collection |
| 7133 * @param {Array|Object|string} collection The collection to iterate over. |
| 7134 * @param {...(Function|Function[]|Object|Object[]|string|string[])} iterate
es |
| 7135 * The iteratees to sort by, specified as individual values or arrays of va
lues. |
| 7136 * @returns {Array} Returns the new sorted array. |
| 7137 * @example |
| 7138 * |
| 7139 * var users = [ |
| 7140 * { 'user': 'fred', 'age': 48 }, |
| 7141 * { 'user': 'barney', 'age': 36 }, |
| 7142 * { 'user': 'fred', 'age': 42 }, |
| 7143 * { 'user': 'barney', 'age': 34 } |
| 7144 * ]; |
| 7145 * |
| 7146 * _.map(_.sortByAll(users, ['user', 'age']), _.values); |
| 7147 * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] |
| 7148 * |
| 7149 * _.map(_.sortByAll(users, 'user', function(chr) { |
| 7150 * return Math.floor(chr.age / 10); |
| 7151 * }), _.values); |
| 7152 * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] |
| 7153 */ |
| 7154 var sortByAll = restParam(function(collection, iteratees) { |
| 7155 if (collection == null) { |
| 7156 return []; |
| 7157 } |
| 7158 var guard = iteratees[2]; |
| 7159 if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { |
| 7160 iteratees.length = 1; |
| 7161 } |
| 7162 return baseSortByOrder(collection, baseFlatten(iteratees), []); |
| 7163 }); |
| 7164 |
| 7165 /** |
| 7166 * This method is like `_.sortByAll` except that it allows specifying the |
| 7167 * sort orders of the iteratees to sort by. If `orders` is unspecified, all |
| 7168 * values are sorted in ascending order. Otherwise, a value is sorted in |
| 7169 * ascending order if its corresponding order is "asc", and descending if "d
esc". |
| 7170 * |
| 7171 * If a property name is provided for an iteratee the created `_.property` |
| 7172 * style callback returns the property value of the given element. |
| 7173 * |
| 7174 * If an object is provided for an iteratee the created `_.matches` style |
| 7175 * callback returns `true` for elements that have the properties of the give
n |
| 7176 * object, else `false`. |
| 7177 * |
| 7178 * @static |
| 7179 * @memberOf _ |
| 7180 * @category Collection |
| 7181 * @param {Array|Object|string} collection The collection to iterate over. |
| 7182 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. |
| 7183 * @param {boolean[]} [orders] The sort orders of `iteratees`. |
| 7184 * @param- {Object} [guard] Enables use as a callback for functions like `_.
reduce`. |
| 7185 * @returns {Array} Returns the new sorted array. |
| 7186 * @example |
| 7187 * |
| 7188 * var users = [ |
| 7189 * { 'user': 'fred', 'age': 48 }, |
| 7190 * { 'user': 'barney', 'age': 34 }, |
| 7191 * { 'user': 'fred', 'age': 42 }, |
| 7192 * { 'user': 'barney', 'age': 36 } |
| 7193 * ]; |
| 7194 * |
| 7195 * // sort by `user` in ascending order and by `age` in descending order |
| 7196 * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); |
| 7197 * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] |
| 7198 */ |
| 7199 function sortByOrder(collection, iteratees, orders, guard) { |
| 7200 if (collection == null) { |
| 7201 return []; |
| 7202 } |
| 7203 if (guard && isIterateeCall(iteratees, orders, guard)) { |
| 7204 orders = undefined; |
| 7205 } |
| 7206 if (!isArray(iteratees)) { |
| 7207 iteratees = iteratees == null ? [] : [iteratees]; |
| 7208 } |
| 7209 if (!isArray(orders)) { |
| 7210 orders = orders == null ? [] : [orders]; |
| 7211 } |
| 7212 return baseSortByOrder(collection, iteratees, orders); |
| 7213 } |
| 7214 |
| 7215 /** |
| 7216 * Performs a deep comparison between each element in `collection` and the |
| 7217 * source object, returning an array of all elements that have equivalent |
| 7218 * property values. |
| 7219 * |
| 7220 * **Note:** This method supports comparing arrays, booleans, `Date` objects
, |
| 7221 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
| 7222 * their own, not inherited, enumerable properties. For comparing a single |
| 7223 * own or inherited property value see `_.matchesProperty`. |
| 7224 * |
| 7225 * @static |
| 7226 * @memberOf _ |
| 7227 * @category Collection |
| 7228 * @param {Array|Object|string} collection The collection to search. |
| 7229 * @param {Object} source The object of property values to match. |
| 7230 * @returns {Array} Returns the new filtered array. |
| 7231 * @example |
| 7232 * |
| 7233 * var users = [ |
| 7234 * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, |
| 7235 * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'd
ino'] } |
| 7236 * ]; |
| 7237 * |
| 7238 * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); |
| 7239 * // => ['barney'] |
| 7240 * |
| 7241 * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); |
| 7242 * // => ['fred'] |
| 7243 */ |
| 7244 function where(collection, source) { |
| 7245 return filter(collection, baseMatches(source)); |
| 7246 } |
| 7247 |
| 7248 /*------------------------------------------------------------------------*/ |
| 7249 |
| 7250 /** |
| 7251 * Gets the number of milliseconds that have elapsed since the Unix epoch |
| 7252 * (1 January 1970 00:00:00 UTC). |
| 7253 * |
| 7254 * @static |
| 7255 * @memberOf _ |
| 7256 * @category Date |
| 7257 * @example |
| 7258 * |
| 7259 * _.defer(function(stamp) { |
| 7260 * console.log(_.now() - stamp); |
| 7261 * }, _.now()); |
| 7262 * // => logs the number of milliseconds it took for the deferred function t
o be invoked |
| 7263 */ |
| 7264 var now = nativeNow || function() { |
| 7265 return new Date().getTime(); |
| 7266 }; |
| 7267 |
| 7268 /*------------------------------------------------------------------------*/ |
| 7269 |
| 7270 /** |
| 7271 * The opposite of `_.before`; this method creates a function that invokes |
| 7272 * `func` once it's called `n` or more times. |
| 7273 * |
| 7274 * @static |
| 7275 * @memberOf _ |
| 7276 * @category Function |
| 7277 * @param {number} n The number of calls before `func` is invoked. |
| 7278 * @param {Function} func The function to restrict. |
| 7279 * @returns {Function} Returns the new restricted function. |
| 7280 * @example |
| 7281 * |
| 7282 * var saves = ['profile', 'settings']; |
| 7283 * |
| 7284 * var done = _.after(saves.length, function() { |
| 7285 * console.log('done saving!'); |
| 7286 * }); |
| 7287 * |
| 7288 * _.forEach(saves, function(type) { |
| 7289 * asyncSave({ 'type': type, 'complete': done }); |
| 7290 * }); |
| 7291 * // => logs 'done saving!' after the two async saves have completed |
| 7292 */ |
| 7293 function after(n, func) { |
| 7294 if (typeof func != 'function') { |
| 7295 if (typeof n == 'function') { |
| 7296 var temp = n; |
| 7297 n = func; |
| 7298 func = temp; |
| 7299 } else { |
| 7300 throw new TypeError(FUNC_ERROR_TEXT); |
| 7301 } |
| 7302 } |
| 7303 n = nativeIsFinite(n = +n) ? n : 0; |
| 7304 return function() { |
| 7305 if (--n < 1) { |
| 7306 return func.apply(this, arguments); |
| 7307 } |
| 7308 }; |
| 7309 } |
| 7310 |
| 7311 /** |
| 7312 * Creates a function that accepts up to `n` arguments ignoring any |
| 7313 * additional arguments. |
| 7314 * |
| 7315 * @static |
| 7316 * @memberOf _ |
| 7317 * @category Function |
| 7318 * @param {Function} func The function to cap arguments for. |
| 7319 * @param {number} [n=func.length] The arity cap. |
| 7320 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 7321 * @returns {Function} Returns the new function. |
| 7322 * @example |
| 7323 * |
| 7324 * _.map(['6', '8', '10'], _.ary(parseInt, 1)); |
| 7325 * // => [6, 8, 10] |
| 7326 */ |
| 7327 function ary(func, n, guard) { |
| 7328 if (guard && isIterateeCall(func, n, guard)) { |
| 7329 n = undefined; |
| 7330 } |
| 7331 n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); |
| 7332 return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, unde
fined, n); |
| 7333 } |
| 7334 |
| 7335 /** |
| 7336 * Creates a function that invokes `func`, with the `this` binding and argum
ents |
| 7337 * of the created function, while it's called less than `n` times. Subsequen
t |
| 7338 * calls to the created function return the result of the last `func` invoca
tion. |
| 7339 * |
| 7340 * @static |
| 7341 * @memberOf _ |
| 7342 * @category Function |
| 7343 * @param {number} n The number of calls at which `func` is no longer invoke
d. |
| 7344 * @param {Function} func The function to restrict. |
| 7345 * @returns {Function} Returns the new restricted function. |
| 7346 * @example |
| 7347 * |
| 7348 * jQuery('#add').on('click', _.before(5, addContactToList)); |
| 7349 * // => allows adding up to 4 contacts to the list |
| 7350 */ |
| 7351 function before(n, func) { |
| 7352 var result; |
| 7353 if (typeof func != 'function') { |
| 7354 if (typeof n == 'function') { |
| 7355 var temp = n; |
| 7356 n = func; |
| 7357 func = temp; |
| 7358 } else { |
| 7359 throw new TypeError(FUNC_ERROR_TEXT); |
| 7360 } |
| 7361 } |
| 7362 return function() { |
| 7363 if (--n > 0) { |
| 7364 result = func.apply(this, arguments); |
| 7365 } |
| 7366 if (n <= 1) { |
| 7367 func = undefined; |
| 7368 } |
| 7369 return result; |
| 7370 }; |
| 7371 } |
| 7372 |
| 7373 /** |
| 7374 * Creates a function that invokes `func` with the `this` binding of `thisAr
g` |
| 7375 * and prepends any additional `_.bind` arguments to those provided to the |
| 7376 * bound function. |
| 7377 * |
| 7378 * The `_.bind.placeholder` value, which defaults to `_` in monolithic build
s, |
| 7379 * may be used as a placeholder for partially applied arguments. |
| 7380 * |
| 7381 * **Note:** Unlike native `Function#bind` this method does not set the "len
gth" |
| 7382 * property of bound functions. |
| 7383 * |
| 7384 * @static |
| 7385 * @memberOf _ |
| 7386 * @category Function |
| 7387 * @param {Function} func The function to bind. |
| 7388 * @param {*} thisArg The `this` binding of `func`. |
| 7389 * @param {...*} [partials] The arguments to be partially applied. |
| 7390 * @returns {Function} Returns the new bound function. |
| 7391 * @example |
| 7392 * |
| 7393 * var greet = function(greeting, punctuation) { |
| 7394 * return greeting + ' ' + this.user + punctuation; |
| 7395 * }; |
| 7396 * |
| 7397 * var object = { 'user': 'fred' }; |
| 7398 * |
| 7399 * var bound = _.bind(greet, object, 'hi'); |
| 7400 * bound('!'); |
| 7401 * // => 'hi fred!' |
| 7402 * |
| 7403 * // using placeholders |
| 7404 * var bound = _.bind(greet, object, _, '!'); |
| 7405 * bound('hi'); |
| 7406 * // => 'hi fred!' |
| 7407 */ |
| 7408 var bind = restParam(function(func, thisArg, partials) { |
| 7409 var bitmask = BIND_FLAG; |
| 7410 if (partials.length) { |
| 7411 var holders = replaceHolders(partials, bind.placeholder); |
| 7412 bitmask |= PARTIAL_FLAG; |
| 7413 } |
| 7414 return createWrapper(func, bitmask, thisArg, partials, holders); |
| 7415 }); |
| 7416 |
| 7417 /** |
| 7418 * Binds methods of an object to the object itself, overwriting the existing |
| 7419 * method. Method names may be specified as individual arguments or as array
s |
| 7420 * of method names. If no method names are provided all enumerable function |
| 7421 * properties, own and inherited, of `object` are bound. |
| 7422 * |
| 7423 * **Note:** This method does not set the "length" property of bound functio
ns. |
| 7424 * |
| 7425 * @static |
| 7426 * @memberOf _ |
| 7427 * @category Function |
| 7428 * @param {Object} object The object to bind and assign the bound methods to
. |
| 7429 * @param {...(string|string[])} [methodNames] The object method names to bi
nd, |
| 7430 * specified as individual method names or arrays of method names. |
| 7431 * @returns {Object} Returns `object`. |
| 7432 * @example |
| 7433 * |
| 7434 * var view = { |
| 7435 * 'label': 'docs', |
| 7436 * 'onClick': function() { |
| 7437 * console.log('clicked ' + this.label); |
| 7438 * } |
| 7439 * }; |
| 7440 * |
| 7441 * _.bindAll(view); |
| 7442 * jQuery('#docs').on('click', view.onClick); |
| 7443 * // => logs 'clicked docs' when the element is clicked |
| 7444 */ |
| 7445 var bindAll = restParam(function(object, methodNames) { |
| 7446 methodNames = methodNames.length ? baseFlatten(methodNames) : functions(ob
ject); |
| 7447 |
| 7448 var index = -1, |
| 7449 length = methodNames.length; |
| 7450 |
| 7451 while (++index < length) { |
| 7452 var key = methodNames[index]; |
| 7453 object[key] = createWrapper(object[key], BIND_FLAG, object); |
| 7454 } |
| 7455 return object; |
| 7456 }); |
| 7457 |
| 7458 /** |
| 7459 * Creates a function that invokes the method at `object[key]` and prepends |
| 7460 * any additional `_.bindKey` arguments to those provided to the bound funct
ion. |
| 7461 * |
| 7462 * This method differs from `_.bind` by allowing bound functions to referenc
e |
| 7463 * methods that may be redefined or don't yet exist. |
| 7464 * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-funct
ion-definition-pattern) |
| 7465 * for more details. |
| 7466 * |
| 7467 * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic |
| 7468 * builds, may be used as a placeholder for partially applied arguments. |
| 7469 * |
| 7470 * @static |
| 7471 * @memberOf _ |
| 7472 * @category Function |
| 7473 * @param {Object} object The object the method belongs to. |
| 7474 * @param {string} key The key of the method. |
| 7475 * @param {...*} [partials] The arguments to be partially applied. |
| 7476 * @returns {Function} Returns the new bound function. |
| 7477 * @example |
| 7478 * |
| 7479 * var object = { |
| 7480 * 'user': 'fred', |
| 7481 * 'greet': function(greeting, punctuation) { |
| 7482 * return greeting + ' ' + this.user + punctuation; |
| 7483 * } |
| 7484 * }; |
| 7485 * |
| 7486 * var bound = _.bindKey(object, 'greet', 'hi'); |
| 7487 * bound('!'); |
| 7488 * // => 'hi fred!' |
| 7489 * |
| 7490 * object.greet = function(greeting, punctuation) { |
| 7491 * return greeting + 'ya ' + this.user + punctuation; |
| 7492 * }; |
| 7493 * |
| 7494 * bound('!'); |
| 7495 * // => 'hiya fred!' |
| 7496 * |
| 7497 * // using placeholders |
| 7498 * var bound = _.bindKey(object, 'greet', _, '!'); |
| 7499 * bound('hi'); |
| 7500 * // => 'hiya fred!' |
| 7501 */ |
| 7502 var bindKey = restParam(function(object, key, partials) { |
| 7503 var bitmask = BIND_FLAG | BIND_KEY_FLAG; |
| 7504 if (partials.length) { |
| 7505 var holders = replaceHolders(partials, bindKey.placeholder); |
| 7506 bitmask |= PARTIAL_FLAG; |
| 7507 } |
| 7508 return createWrapper(key, bitmask, object, partials, holders); |
| 7509 }); |
| 7510 |
| 7511 /** |
| 7512 * Creates a function that accepts one or more arguments of `func` that when |
| 7513 * called either invokes `func` returning its result, if all `func` argument
s |
| 7514 * have been provided, or returns a function that accepts one or more of the |
| 7515 * remaining `func` arguments, and so on. The arity of `func` may be specifi
ed |
| 7516 * if `func.length` is not sufficient. |
| 7517 * |
| 7518 * The `_.curry.placeholder` value, which defaults to `_` in monolithic buil
ds, |
| 7519 * may be used as a placeholder for provided arguments. |
| 7520 * |
| 7521 * **Note:** This method does not set the "length" property of curried funct
ions. |
| 7522 * |
| 7523 * @static |
| 7524 * @memberOf _ |
| 7525 * @category Function |
| 7526 * @param {Function} func The function to curry. |
| 7527 * @param {number} [arity=func.length] The arity of `func`. |
| 7528 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 7529 * @returns {Function} Returns the new curried function. |
| 7530 * @example |
| 7531 * |
| 7532 * var abc = function(a, b, c) { |
| 7533 * return [a, b, c]; |
| 7534 * }; |
| 7535 * |
| 7536 * var curried = _.curry(abc); |
| 7537 * |
| 7538 * curried(1)(2)(3); |
| 7539 * // => [1, 2, 3] |
| 7540 * |
| 7541 * curried(1, 2)(3); |
| 7542 * // => [1, 2, 3] |
| 7543 * |
| 7544 * curried(1, 2, 3); |
| 7545 * // => [1, 2, 3] |
| 7546 * |
| 7547 * // using placeholders |
| 7548 * curried(1)(_, 3)(2); |
| 7549 * // => [1, 2, 3] |
| 7550 */ |
| 7551 var curry = createCurry(CURRY_FLAG); |
| 7552 |
| 7553 /** |
| 7554 * This method is like `_.curry` except that arguments are applied to `func` |
| 7555 * in the manner of `_.partialRight` instead of `_.partial`. |
| 7556 * |
| 7557 * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic |
| 7558 * builds, may be used as a placeholder for provided arguments. |
| 7559 * |
| 7560 * **Note:** This method does not set the "length" property of curried funct
ions. |
| 7561 * |
| 7562 * @static |
| 7563 * @memberOf _ |
| 7564 * @category Function |
| 7565 * @param {Function} func The function to curry. |
| 7566 * @param {number} [arity=func.length] The arity of `func`. |
| 7567 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 7568 * @returns {Function} Returns the new curried function. |
| 7569 * @example |
| 7570 * |
| 7571 * var abc = function(a, b, c) { |
| 7572 * return [a, b, c]; |
| 7573 * }; |
| 7574 * |
| 7575 * var curried = _.curryRight(abc); |
| 7576 * |
| 7577 * curried(3)(2)(1); |
| 7578 * // => [1, 2, 3] |
| 7579 * |
| 7580 * curried(2, 3)(1); |
| 7581 * // => [1, 2, 3] |
| 7582 * |
| 7583 * curried(1, 2, 3); |
| 7584 * // => [1, 2, 3] |
| 7585 * |
| 7586 * // using placeholders |
| 7587 * curried(3)(1, _)(2); |
| 7588 * // => [1, 2, 3] |
| 7589 */ |
| 7590 var curryRight = createCurry(CURRY_RIGHT_FLAG); |
| 7591 |
| 7592 /** |
| 7593 * Creates a debounced function that delays invoking `func` until after `wai
t` |
| 7594 * milliseconds have elapsed since the last time the debounced function was |
| 7595 * invoked. The debounced function comes with a `cancel` method to cancel |
| 7596 * delayed invocations. Provide an options object to indicate that `func` |
| 7597 * should be invoked on the leading and/or trailing edge of the `wait` timeo
ut. |
| 7598 * Subsequent calls to the debounced function return the result of the last |
| 7599 * `func` invocation. |
| 7600 * |
| 7601 * **Note:** If `leading` and `trailing` options are `true`, `func` is invok
ed |
| 7602 * on the trailing edge of the timeout only if the the debounced function is |
| 7603 * invoked more than once during the `wait` timeout. |
| 7604 * |
| 7605 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-a
nd-throttle-visual-explanation) |
| 7606 * for details over the differences between `_.debounce` and `_.throttle`. |
| 7607 * |
| 7608 * @static |
| 7609 * @memberOf _ |
| 7610 * @category Function |
| 7611 * @param {Function} func The function to debounce. |
| 7612 * @param {number} [wait=0] The number of milliseconds to delay. |
| 7613 * @param {Object} [options] The options object. |
| 7614 * @param {boolean} [options.leading=false] Specify invoking on the leading |
| 7615 * edge of the timeout. |
| 7616 * @param {number} [options.maxWait] The maximum time `func` is allowed to b
e |
| 7617 * delayed before it's invoked. |
| 7618 * @param {boolean} [options.trailing=true] Specify invoking on the trailing |
| 7619 * edge of the timeout. |
| 7620 * @returns {Function} Returns the new debounced function. |
| 7621 * @example |
| 7622 * |
| 7623 * // avoid costly calculations while the window size is in flux |
| 7624 * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); |
| 7625 * |
| 7626 * // invoke `sendMail` when the click event is fired, debouncing subsequent
calls |
| 7627 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { |
| 7628 * 'leading': true, |
| 7629 * 'trailing': false |
| 7630 * })); |
| 7631 * |
| 7632 * // ensure `batchLog` is invoked once after 1 second of debounced calls |
| 7633 * var source = new EventSource('/stream'); |
| 7634 * jQuery(source).on('message', _.debounce(batchLog, 250, { |
| 7635 * 'maxWait': 1000 |
| 7636 * })); |
| 7637 * |
| 7638 * // cancel a debounced call |
| 7639 * var todoChanges = _.debounce(batchLog, 1000); |
| 7640 * Object.observe(models.todo, todoChanges); |
| 7641 * |
| 7642 * Object.observe(models, function(changes) { |
| 7643 * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { |
| 7644 * todoChanges.cancel(); |
| 7645 * } |
| 7646 * }, ['delete']); |
| 7647 * |
| 7648 * // ...at some point `models.todo` is changed |
| 7649 * models.todo.completed = true; |
| 7650 * |
| 7651 * // ...before 1 second has passed `models.todo` is deleted |
| 7652 * // which cancels the debounced `todoChanges` call |
| 7653 * delete models.todo; |
| 7654 */ |
| 7655 function debounce(func, wait, options) { |
| 7656 var args, |
| 7657 maxTimeoutId, |
| 7658 result, |
| 7659 stamp, |
| 7660 thisArg, |
| 7661 timeoutId, |
| 7662 trailingCall, |
| 7663 lastCalled = 0, |
| 7664 maxWait = false, |
| 7665 trailing = true; |
| 7666 |
| 7667 if (typeof func != 'function') { |
| 7668 throw new TypeError(FUNC_ERROR_TEXT); |
| 7669 } |
| 7670 wait = wait < 0 ? 0 : (+wait || 0); |
| 7671 if (options === true) { |
| 7672 var leading = true; |
| 7673 trailing = false; |
| 7674 } else if (isObject(options)) { |
| 7675 leading = !!options.leading; |
| 7676 maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait)
; |
| 7677 trailing = 'trailing' in options ? !!options.trailing : trailing; |
| 7678 } |
| 7679 |
| 7680 function cancel() { |
| 7681 if (timeoutId) { |
| 7682 clearTimeout(timeoutId); |
| 7683 } |
| 7684 if (maxTimeoutId) { |
| 7685 clearTimeout(maxTimeoutId); |
| 7686 } |
| 7687 lastCalled = 0; |
| 7688 maxTimeoutId = timeoutId = trailingCall = undefined; |
| 7689 } |
| 7690 |
| 7691 function complete(isCalled, id) { |
| 7692 if (id) { |
| 7693 clearTimeout(id); |
| 7694 } |
| 7695 maxTimeoutId = timeoutId = trailingCall = undefined; |
| 7696 if (isCalled) { |
| 7697 lastCalled = now(); |
| 7698 result = func.apply(thisArg, args); |
| 7699 if (!timeoutId && !maxTimeoutId) { |
| 7700 args = thisArg = undefined; |
| 7701 } |
| 7702 } |
| 7703 } |
| 7704 |
| 7705 function delayed() { |
| 7706 var remaining = wait - (now() - stamp); |
| 7707 if (remaining <= 0 || remaining > wait) { |
| 7708 complete(trailingCall, maxTimeoutId); |
| 7709 } else { |
| 7710 timeoutId = setTimeout(delayed, remaining); |
| 7711 } |
| 7712 } |
| 7713 |
| 7714 function maxDelayed() { |
| 7715 complete(trailing, timeoutId); |
| 7716 } |
| 7717 |
| 7718 function debounced() { |
| 7719 args = arguments; |
| 7720 stamp = now(); |
| 7721 thisArg = this; |
| 7722 trailingCall = trailing && (timeoutId || !leading); |
| 7723 |
| 7724 if (maxWait === false) { |
| 7725 var leadingCall = leading && !timeoutId; |
| 7726 } else { |
| 7727 if (!maxTimeoutId && !leading) { |
| 7728 lastCalled = stamp; |
| 7729 } |
| 7730 var remaining = maxWait - (stamp - lastCalled), |
| 7731 isCalled = remaining <= 0 || remaining > maxWait; |
| 7732 |
| 7733 if (isCalled) { |
| 7734 if (maxTimeoutId) { |
| 7735 maxTimeoutId = clearTimeout(maxTimeoutId); |
| 7736 } |
| 7737 lastCalled = stamp; |
| 7738 result = func.apply(thisArg, args); |
| 7739 } |
| 7740 else if (!maxTimeoutId) { |
| 7741 maxTimeoutId = setTimeout(maxDelayed, remaining); |
| 7742 } |
| 7743 } |
| 7744 if (isCalled && timeoutId) { |
| 7745 timeoutId = clearTimeout(timeoutId); |
| 7746 } |
| 7747 else if (!timeoutId && wait !== maxWait) { |
| 7748 timeoutId = setTimeout(delayed, wait); |
| 7749 } |
| 7750 if (leadingCall) { |
| 7751 isCalled = true; |
| 7752 result = func.apply(thisArg, args); |
| 7753 } |
| 7754 if (isCalled && !timeoutId && !maxTimeoutId) { |
| 7755 args = thisArg = undefined; |
| 7756 } |
| 7757 return result; |
| 7758 } |
| 7759 debounced.cancel = cancel; |
| 7760 return debounced; |
| 7761 } |
| 7762 |
| 7763 /** |
| 7764 * Defers invoking the `func` until the current call stack has cleared. Any |
| 7765 * additional arguments are provided to `func` when it's invoked. |
| 7766 * |
| 7767 * @static |
| 7768 * @memberOf _ |
| 7769 * @category Function |
| 7770 * @param {Function} func The function to defer. |
| 7771 * @param {...*} [args] The arguments to invoke the function with. |
| 7772 * @returns {number} Returns the timer id. |
| 7773 * @example |
| 7774 * |
| 7775 * _.defer(function(text) { |
| 7776 * console.log(text); |
| 7777 * }, 'deferred'); |
| 7778 * // logs 'deferred' after one or more milliseconds |
| 7779 */ |
| 7780 var defer = restParam(function(func, args) { |
| 7781 return baseDelay(func, 1, args); |
| 7782 }); |
| 7783 |
| 7784 /** |
| 7785 * Invokes `func` after `wait` milliseconds. Any additional arguments are |
| 7786 * provided to `func` when it's invoked. |
| 7787 * |
| 7788 * @static |
| 7789 * @memberOf _ |
| 7790 * @category Function |
| 7791 * @param {Function} func The function to delay. |
| 7792 * @param {number} wait The number of milliseconds to delay invocation. |
| 7793 * @param {...*} [args] The arguments to invoke the function with. |
| 7794 * @returns {number} Returns the timer id. |
| 7795 * @example |
| 7796 * |
| 7797 * _.delay(function(text) { |
| 7798 * console.log(text); |
| 7799 * }, 1000, 'later'); |
| 7800 * // => logs 'later' after one second |
| 7801 */ |
| 7802 var delay = restParam(function(func, wait, args) { |
| 7803 return baseDelay(func, wait, args); |
| 7804 }); |
| 7805 |
| 7806 /** |
| 7807 * Creates a function that returns the result of invoking the provided |
| 7808 * functions with the `this` binding of the created function, where each |
| 7809 * successive invocation is supplied the return value of the previous. |
| 7810 * |
| 7811 * @static |
| 7812 * @memberOf _ |
| 7813 * @category Function |
| 7814 * @param {...Function} [funcs] Functions to invoke. |
| 7815 * @returns {Function} Returns the new function. |
| 7816 * @example |
| 7817 * |
| 7818 * function square(n) { |
| 7819 * return n * n; |
| 7820 * } |
| 7821 * |
| 7822 * var addSquare = _.flow(_.add, square); |
| 7823 * addSquare(1, 2); |
| 7824 * // => 9 |
| 7825 */ |
| 7826 var flow = createFlow(); |
| 7827 |
| 7828 /** |
| 7829 * This method is like `_.flow` except that it creates a function that |
| 7830 * invokes the provided functions from right to left. |
| 7831 * |
| 7832 * @static |
| 7833 * @memberOf _ |
| 7834 * @alias backflow, compose |
| 7835 * @category Function |
| 7836 * @param {...Function} [funcs] Functions to invoke. |
| 7837 * @returns {Function} Returns the new function. |
| 7838 * @example |
| 7839 * |
| 7840 * function square(n) { |
| 7841 * return n * n; |
| 7842 * } |
| 7843 * |
| 7844 * var addSquare = _.flowRight(square, _.add); |
| 7845 * addSquare(1, 2); |
| 7846 * // => 9 |
| 7847 */ |
| 7848 var flowRight = createFlow(true); |
| 7849 |
| 7850 /** |
| 7851 * Creates a function that memoizes the result of `func`. If `resolver` is |
| 7852 * provided it determines the cache key for storing the result based on the |
| 7853 * arguments provided to the memoized function. By default, the first argume
nt |
| 7854 * provided to the memoized function is coerced to a string and used as the |
| 7855 * cache key. The `func` is invoked with the `this` binding of the memoized |
| 7856 * function. |
| 7857 * |
| 7858 * **Note:** The cache is exposed as the `cache` property on the memoized |
| 7859 * function. Its creation may be customized by replacing the `_.memoize.Cach
e` |
| 7860 * constructor with one whose instances implement the [`Map`](http://ecma-in
ternational.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) |
| 7861 * method interface of `get`, `has`, and `set`. |
| 7862 * |
| 7863 * @static |
| 7864 * @memberOf _ |
| 7865 * @category Function |
| 7866 * @param {Function} func The function to have its output memoized. |
| 7867 * @param {Function} [resolver] The function to resolve the cache key. |
| 7868 * @returns {Function} Returns the new memoizing function. |
| 7869 * @example |
| 7870 * |
| 7871 * var upperCase = _.memoize(function(string) { |
| 7872 * return string.toUpperCase(); |
| 7873 * }); |
| 7874 * |
| 7875 * upperCase('fred'); |
| 7876 * // => 'FRED' |
| 7877 * |
| 7878 * // modifying the result cache |
| 7879 * upperCase.cache.set('fred', 'BARNEY'); |
| 7880 * upperCase('fred'); |
| 7881 * // => 'BARNEY' |
| 7882 * |
| 7883 * // replacing `_.memoize.Cache` |
| 7884 * var object = { 'user': 'fred' }; |
| 7885 * var other = { 'user': 'barney' }; |
| 7886 * var identity = _.memoize(_.identity); |
| 7887 * |
| 7888 * identity(object); |
| 7889 * // => { 'user': 'fred' } |
| 7890 * identity(other); |
| 7891 * // => { 'user': 'fred' } |
| 7892 * |
| 7893 * _.memoize.Cache = WeakMap; |
| 7894 * var identity = _.memoize(_.identity); |
| 7895 * |
| 7896 * identity(object); |
| 7897 * // => { 'user': 'fred' } |
| 7898 * identity(other); |
| 7899 * // => { 'user': 'barney' } |
| 7900 */ |
| 7901 function memoize(func, resolver) { |
| 7902 if (typeof func != 'function' || (resolver && typeof resolver != 'function
')) { |
| 7903 throw new TypeError(FUNC_ERROR_TEXT); |
| 7904 } |
| 7905 var memoized = function() { |
| 7906 var args = arguments, |
| 7907 key = resolver ? resolver.apply(this, args) : args[0], |
| 7908 cache = memoized.cache; |
| 7909 |
| 7910 if (cache.has(key)) { |
| 7911 return cache.get(key); |
| 7912 } |
| 7913 var result = func.apply(this, args); |
| 7914 memoized.cache = cache.set(key, result); |
| 7915 return result; |
| 7916 }; |
| 7917 memoized.cache = new memoize.Cache; |
| 7918 return memoized; |
| 7919 } |
| 7920 |
| 7921 /** |
| 7922 * Creates a function that runs each argument through a corresponding |
| 7923 * transform function. |
| 7924 * |
| 7925 * @static |
| 7926 * @memberOf _ |
| 7927 * @category Function |
| 7928 * @param {Function} func The function to wrap. |
| 7929 * @param {...(Function|Function[])} [transforms] The functions to transform |
| 7930 * arguments, specified as individual functions or arrays of functions. |
| 7931 * @returns {Function} Returns the new function. |
| 7932 * @example |
| 7933 * |
| 7934 * function doubled(n) { |
| 7935 * return n * 2; |
| 7936 * } |
| 7937 * |
| 7938 * function square(n) { |
| 7939 * return n * n; |
| 7940 * } |
| 7941 * |
| 7942 * var modded = _.modArgs(function(x, y) { |
| 7943 * return [x, y]; |
| 7944 * }, square, doubled); |
| 7945 * |
| 7946 * modded(1, 2); |
| 7947 * // => [1, 4] |
| 7948 * |
| 7949 * modded(5, 10); |
| 7950 * // => [25, 20] |
| 7951 */ |
| 7952 var modArgs = restParam(function(func, transforms) { |
| 7953 transforms = baseFlatten(transforms); |
| 7954 if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction))
{ |
| 7955 throw new TypeError(FUNC_ERROR_TEXT); |
| 7956 } |
| 7957 var length = transforms.length; |
| 7958 return restParam(function(args) { |
| 7959 var index = nativeMin(args.length, length); |
| 7960 while (index--) { |
| 7961 args[index] = transforms[index](args[index]); |
| 7962 } |
| 7963 return func.apply(this, args); |
| 7964 }); |
| 7965 }); |
| 7966 |
| 7967 /** |
| 7968 * Creates a function that negates the result of the predicate `func`. The |
| 7969 * `func` predicate is invoked with the `this` binding and arguments of the |
| 7970 * created function. |
| 7971 * |
| 7972 * @static |
| 7973 * @memberOf _ |
| 7974 * @category Function |
| 7975 * @param {Function} predicate The predicate to negate. |
| 7976 * @returns {Function} Returns the new function. |
| 7977 * @example |
| 7978 * |
| 7979 * function isEven(n) { |
| 7980 * return n % 2 == 0; |
| 7981 * } |
| 7982 * |
| 7983 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); |
| 7984 * // => [1, 3, 5] |
| 7985 */ |
| 7986 function negate(predicate) { |
| 7987 if (typeof predicate != 'function') { |
| 7988 throw new TypeError(FUNC_ERROR_TEXT); |
| 7989 } |
| 7990 return function() { |
| 7991 return !predicate.apply(this, arguments); |
| 7992 }; |
| 7993 } |
| 7994 |
| 7995 /** |
| 7996 * Creates a function that is restricted to invoking `func` once. Repeat cal
ls |
| 7997 * to the function return the value of the first call. The `func` is invoked |
| 7998 * with the `this` binding and arguments of the created function. |
| 7999 * |
| 8000 * @static |
| 8001 * @memberOf _ |
| 8002 * @category Function |
| 8003 * @param {Function} func The function to restrict. |
| 8004 * @returns {Function} Returns the new restricted function. |
| 8005 * @example |
| 8006 * |
| 8007 * var initialize = _.once(createApplication); |
| 8008 * initialize(); |
| 8009 * initialize(); |
| 8010 * // `initialize` invokes `createApplication` once |
| 8011 */ |
| 8012 function once(func) { |
| 8013 return before(2, func); |
| 8014 } |
| 8015 |
| 8016 /** |
| 8017 * Creates a function that invokes `func` with `partial` arguments prepended |
| 8018 * to those provided to the new function. This method is like `_.bind` excep
t |
| 8019 * it does **not** alter the `this` binding. |
| 8020 * |
| 8021 * The `_.partial.placeholder` value, which defaults to `_` in monolithic |
| 8022 * builds, may be used as a placeholder for partially applied arguments. |
| 8023 * |
| 8024 * **Note:** This method does not set the "length" property of partially |
| 8025 * applied functions. |
| 8026 * |
| 8027 * @static |
| 8028 * @memberOf _ |
| 8029 * @category Function |
| 8030 * @param {Function} func The function to partially apply arguments to. |
| 8031 * @param {...*} [partials] The arguments to be partially applied. |
| 8032 * @returns {Function} Returns the new partially applied function. |
| 8033 * @example |
| 8034 * |
| 8035 * var greet = function(greeting, name) { |
| 8036 * return greeting + ' ' + name; |
| 8037 * }; |
| 8038 * |
| 8039 * var sayHelloTo = _.partial(greet, 'hello'); |
| 8040 * sayHelloTo('fred'); |
| 8041 * // => 'hello fred' |
| 8042 * |
| 8043 * // using placeholders |
| 8044 * var greetFred = _.partial(greet, _, 'fred'); |
| 8045 * greetFred('hi'); |
| 8046 * // => 'hi fred' |
| 8047 */ |
| 8048 var partial = createPartial(PARTIAL_FLAG); |
| 8049 |
| 8050 /** |
| 8051 * This method is like `_.partial` except that partially applied arguments |
| 8052 * are appended to those provided to the new function. |
| 8053 * |
| 8054 * The `_.partialRight.placeholder` value, which defaults to `_` in monolith
ic |
| 8055 * builds, may be used as a placeholder for partially applied arguments. |
| 8056 * |
| 8057 * **Note:** This method does not set the "length" property of partially |
| 8058 * applied functions. |
| 8059 * |
| 8060 * @static |
| 8061 * @memberOf _ |
| 8062 * @category Function |
| 8063 * @param {Function} func The function to partially apply arguments to. |
| 8064 * @param {...*} [partials] The arguments to be partially applied. |
| 8065 * @returns {Function} Returns the new partially applied function. |
| 8066 * @example |
| 8067 * |
| 8068 * var greet = function(greeting, name) { |
| 8069 * return greeting + ' ' + name; |
| 8070 * }; |
| 8071 * |
| 8072 * var greetFred = _.partialRight(greet, 'fred'); |
| 8073 * greetFred('hi'); |
| 8074 * // => 'hi fred' |
| 8075 * |
| 8076 * // using placeholders |
| 8077 * var sayHelloTo = _.partialRight(greet, 'hello', _); |
| 8078 * sayHelloTo('fred'); |
| 8079 * // => 'hello fred' |
| 8080 */ |
| 8081 var partialRight = createPartial(PARTIAL_RIGHT_FLAG); |
| 8082 |
| 8083 /** |
| 8084 * Creates a function that invokes `func` with arguments arranged according |
| 8085 * to the specified indexes where the argument value at the first index is |
| 8086 * provided as the first argument, the argument value at the second index is |
| 8087 * provided as the second argument, and so on. |
| 8088 * |
| 8089 * @static |
| 8090 * @memberOf _ |
| 8091 * @category Function |
| 8092 * @param {Function} func The function to rearrange arguments for. |
| 8093 * @param {...(number|number[])} indexes The arranged argument indexes, |
| 8094 * specified as individual indexes or arrays of indexes. |
| 8095 * @returns {Function} Returns the new function. |
| 8096 * @example |
| 8097 * |
| 8098 * var rearged = _.rearg(function(a, b, c) { |
| 8099 * return [a, b, c]; |
| 8100 * }, 2, 0, 1); |
| 8101 * |
| 8102 * rearged('b', 'c', 'a') |
| 8103 * // => ['a', 'b', 'c'] |
| 8104 * |
| 8105 * var map = _.rearg(_.map, [1, 0]); |
| 8106 * map(function(n) { |
| 8107 * return n * 3; |
| 8108 * }, [1, 2, 3]); |
| 8109 * // => [3, 6, 9] |
| 8110 */ |
| 8111 var rearg = restParam(function(func, indexes) { |
| 8112 return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, ba
seFlatten(indexes)); |
| 8113 }); |
| 8114 |
| 8115 /** |
| 8116 * Creates a function that invokes `func` with the `this` binding of the |
| 8117 * created function and arguments from `start` and beyond provided as an arr
ay. |
| 8118 * |
| 8119 * **Note:** This method is based on the [rest parameter](https://developer.
mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). |
| 8120 * |
| 8121 * @static |
| 8122 * @memberOf _ |
| 8123 * @category Function |
| 8124 * @param {Function} func The function to apply a rest parameter to. |
| 8125 * @param {number} [start=func.length-1] The start position of the rest para
meter. |
| 8126 * @returns {Function} Returns the new function. |
| 8127 * @example |
| 8128 * |
| 8129 * var say = _.restParam(function(what, names) { |
| 8130 * return what + ' ' + _.initial(names).join(', ') + |
| 8131 * (_.size(names) > 1 ? ', & ' : '') + _.last(names); |
| 8132 * }); |
| 8133 * |
| 8134 * say('hello', 'fred', 'barney', 'pebbles'); |
| 8135 * // => 'hello fred, barney, & pebbles' |
| 8136 */ |
| 8137 function restParam(func, start) { |
| 8138 if (typeof func != 'function') { |
| 8139 throw new TypeError(FUNC_ERROR_TEXT); |
| 8140 } |
| 8141 start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0),
0); |
| 8142 return function() { |
| 8143 var args = arguments, |
| 8144 index = -1, |
| 8145 length = nativeMax(args.length - start, 0), |
| 8146 rest = Array(length); |
| 8147 |
| 8148 while (++index < length) { |
| 8149 rest[index] = args[start + index]; |
| 8150 } |
| 8151 switch (start) { |
| 8152 case 0: return func.call(this, rest); |
| 8153 case 1: return func.call(this, args[0], rest); |
| 8154 case 2: return func.call(this, args[0], args[1], rest); |
| 8155 } |
| 8156 var otherArgs = Array(start + 1); |
| 8157 index = -1; |
| 8158 while (++index < start) { |
| 8159 otherArgs[index] = args[index]; |
| 8160 } |
| 8161 otherArgs[start] = rest; |
| 8162 return func.apply(this, otherArgs); |
| 8163 }; |
| 8164 } |
| 8165 |
| 8166 /** |
| 8167 * Creates a function that invokes `func` with the `this` binding of the cre
ated |
| 8168 * function and an array of arguments much like [`Function#apply`](https://e
s5.github.io/#x15.3.4.3). |
| 8169 * |
| 8170 * **Note:** This method is based on the [spread operator](https://developer
.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator). |
| 8171 * |
| 8172 * @static |
| 8173 * @memberOf _ |
| 8174 * @category Function |
| 8175 * @param {Function} func The function to spread arguments over. |
| 8176 * @returns {Function} Returns the new function. |
| 8177 * @example |
| 8178 * |
| 8179 * var say = _.spread(function(who, what) { |
| 8180 * return who + ' says ' + what; |
| 8181 * }); |
| 8182 * |
| 8183 * say(['fred', 'hello']); |
| 8184 * // => 'fred says hello' |
| 8185 * |
| 8186 * // with a Promise |
| 8187 * var numbers = Promise.all([ |
| 8188 * Promise.resolve(40), |
| 8189 * Promise.resolve(36) |
| 8190 * ]); |
| 8191 * |
| 8192 * numbers.then(_.spread(function(x, y) { |
| 8193 * return x + y; |
| 8194 * })); |
| 8195 * // => a Promise of 76 |
| 8196 */ |
| 8197 function spread(func) { |
| 8198 if (typeof func != 'function') { |
| 8199 throw new TypeError(FUNC_ERROR_TEXT); |
| 8200 } |
| 8201 return function(array) { |
| 8202 return func.apply(this, array); |
| 8203 }; |
| 8204 } |
| 8205 |
| 8206 /** |
| 8207 * Creates a throttled function that only invokes `func` at most once per |
| 8208 * every `wait` milliseconds. The throttled function comes with a `cancel` |
| 8209 * method to cancel delayed invocations. Provide an options object to indica
te |
| 8210 * that `func` should be invoked on the leading and/or trailing edge of the |
| 8211 * `wait` timeout. Subsequent calls to the throttled function return the |
| 8212 * result of the last `func` call. |
| 8213 * |
| 8214 * **Note:** If `leading` and `trailing` options are `true`, `func` is invok
ed |
| 8215 * on the trailing edge of the timeout only if the the throttled function is |
| 8216 * invoked more than once during the `wait` timeout. |
| 8217 * |
| 8218 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-a
nd-throttle-visual-explanation) |
| 8219 * for details over the differences between `_.throttle` and `_.debounce`. |
| 8220 * |
| 8221 * @static |
| 8222 * @memberOf _ |
| 8223 * @category Function |
| 8224 * @param {Function} func The function to throttle. |
| 8225 * @param {number} [wait=0] The number of milliseconds to throttle invocatio
ns to. |
| 8226 * @param {Object} [options] The options object. |
| 8227 * @param {boolean} [options.leading=true] Specify invoking on the leading |
| 8228 * edge of the timeout. |
| 8229 * @param {boolean} [options.trailing=true] Specify invoking on the trailing |
| 8230 * edge of the timeout. |
| 8231 * @returns {Function} Returns the new throttled function. |
| 8232 * @example |
| 8233 * |
| 8234 * // avoid excessively updating the position while scrolling |
| 8235 * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); |
| 8236 * |
| 8237 * // invoke `renewToken` when the click event is fired, but not more than o
nce every 5 minutes |
| 8238 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { |
| 8239 * 'trailing': false |
| 8240 * })); |
| 8241 * |
| 8242 * // cancel a trailing throttled call |
| 8243 * jQuery(window).on('popstate', throttled.cancel); |
| 8244 */ |
| 8245 function throttle(func, wait, options) { |
| 8246 var leading = true, |
| 8247 trailing = true; |
| 8248 |
| 8249 if (typeof func != 'function') { |
| 8250 throw new TypeError(FUNC_ERROR_TEXT); |
| 8251 } |
| 8252 if (options === false) { |
| 8253 leading = false; |
| 8254 } else if (isObject(options)) { |
| 8255 leading = 'leading' in options ? !!options.leading : leading; |
| 8256 trailing = 'trailing' in options ? !!options.trailing : trailing; |
| 8257 } |
| 8258 return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trail
ing': trailing }); |
| 8259 } |
| 8260 |
| 8261 /** |
| 8262 * Creates a function that provides `value` to the wrapper function as its |
| 8263 * first argument. Any additional arguments provided to the function are |
| 8264 * appended to those provided to the wrapper function. The wrapper is invoke
d |
| 8265 * with the `this` binding of the created function. |
| 8266 * |
| 8267 * @static |
| 8268 * @memberOf _ |
| 8269 * @category Function |
| 8270 * @param {*} value The value to wrap. |
| 8271 * @param {Function} wrapper The wrapper function. |
| 8272 * @returns {Function} Returns the new function. |
| 8273 * @example |
| 8274 * |
| 8275 * var p = _.wrap(_.escape, function(func, text) { |
| 8276 * return '<p>' + func(text) + '</p>'; |
| 8277 * }); |
| 8278 * |
| 8279 * p('fred, barney, & pebbles'); |
| 8280 * // => '<p>fred, barney, & pebbles</p>' |
| 8281 */ |
| 8282 function wrap(value, wrapper) { |
| 8283 wrapper = wrapper == null ? identity : wrapper; |
| 8284 return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); |
| 8285 } |
| 8286 |
| 8287 /*------------------------------------------------------------------------*/ |
| 8288 |
| 8289 /** |
| 8290 * Creates a clone of `value`. If `isDeep` is `true` nested objects are clon
ed, |
| 8291 * otherwise they are assigned by reference. If `customizer` is provided it'
s |
| 8292 * invoked to produce the cloned values. If `customizer` returns `undefined` |
| 8293 * cloning is handled by the method instead. The `customizer` is bound to |
| 8294 * `thisArg` and invoked with up to three argument; (value [, index|key, obj
ect]). |
| 8295 * |
| 8296 * **Note:** This method is loosely based on the |
| 8297 * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.ht
ml#internal-structured-cloning-algorithm). |
| 8298 * The enumerable properties of `arguments` objects and objects created by |
| 8299 * constructors other than `Object` are cloned to plain `Object` objects. An |
| 8300 * empty object is returned for uncloneable values such as functions, DOM no
des, |
| 8301 * Maps, Sets, and WeakMaps. |
| 8302 * |
| 8303 * @static |
| 8304 * @memberOf _ |
| 8305 * @category Lang |
| 8306 * @param {*} value The value to clone. |
| 8307 * @param {boolean} [isDeep] Specify a deep clone. |
| 8308 * @param {Function} [customizer] The function to customize cloning values. |
| 8309 * @param {*} [thisArg] The `this` binding of `customizer`. |
| 8310 * @returns {*} Returns the cloned value. |
| 8311 * @example |
| 8312 * |
| 8313 * var users = [ |
| 8314 * { 'user': 'barney' }, |
| 8315 * { 'user': 'fred' } |
| 8316 * ]; |
| 8317 * |
| 8318 * var shallow = _.clone(users); |
| 8319 * shallow[0] === users[0]; |
| 8320 * // => true |
| 8321 * |
| 8322 * var deep = _.clone(users, true); |
| 8323 * deep[0] === users[0]; |
| 8324 * // => false |
| 8325 * |
| 8326 * // using a customizer callback |
| 8327 * var el = _.clone(document.body, function(value) { |
| 8328 * if (_.isElement(value)) { |
| 8329 * return value.cloneNode(false); |
| 8330 * } |
| 8331 * }); |
| 8332 * |
| 8333 * el === document.body |
| 8334 * // => false |
| 8335 * el.nodeName |
| 8336 * // => BODY |
| 8337 * el.childNodes.length; |
| 8338 * // => 0 |
| 8339 */ |
| 8340 function clone(value, isDeep, customizer, thisArg) { |
| 8341 if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep,
customizer)) { |
| 8342 isDeep = false; |
| 8343 } |
| 8344 else if (typeof isDeep == 'function') { |
| 8345 thisArg = customizer; |
| 8346 customizer = isDeep; |
| 8347 isDeep = false; |
| 8348 } |
| 8349 return typeof customizer == 'function' |
| 8350 ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3)) |
| 8351 : baseClone(value, isDeep); |
| 8352 } |
| 8353 |
| 8354 /** |
| 8355 * Creates a deep clone of `value`. If `customizer` is provided it's invoked |
| 8356 * to produce the cloned values. If `customizer` returns `undefined` cloning |
| 8357 * is handled by the method instead. The `customizer` is bound to `thisArg` |
| 8358 * and invoked with up to three argument; (value [, index|key, object]). |
| 8359 * |
| 8360 * **Note:** This method is loosely based on the |
| 8361 * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.ht
ml#internal-structured-cloning-algorithm). |
| 8362 * The enumerable properties of `arguments` objects and objects created by |
| 8363 * constructors other than `Object` are cloned to plain `Object` objects. An |
| 8364 * empty object is returned for uncloneable values such as functions, DOM no
des, |
| 8365 * Maps, Sets, and WeakMaps. |
| 8366 * |
| 8367 * @static |
| 8368 * @memberOf _ |
| 8369 * @category Lang |
| 8370 * @param {*} value The value to deep clone. |
| 8371 * @param {Function} [customizer] The function to customize cloning values. |
| 8372 * @param {*} [thisArg] The `this` binding of `customizer`. |
| 8373 * @returns {*} Returns the deep cloned value. |
| 8374 * @example |
| 8375 * |
| 8376 * var users = [ |
| 8377 * { 'user': 'barney' }, |
| 8378 * { 'user': 'fred' } |
| 8379 * ]; |
| 8380 * |
| 8381 * var deep = _.cloneDeep(users); |
| 8382 * deep[0] === users[0]; |
| 8383 * // => false |
| 8384 * |
| 8385 * // using a customizer callback |
| 8386 * var el = _.cloneDeep(document.body, function(value) { |
| 8387 * if (_.isElement(value)) { |
| 8388 * return value.cloneNode(true); |
| 8389 * } |
| 8390 * }); |
| 8391 * |
| 8392 * el === document.body |
| 8393 * // => false |
| 8394 * el.nodeName |
| 8395 * // => BODY |
| 8396 * el.childNodes.length; |
| 8397 * // => 20 |
| 8398 */ |
| 8399 function cloneDeep(value, customizer, thisArg) { |
| 8400 return typeof customizer == 'function' |
| 8401 ? baseClone(value, true, bindCallback(customizer, thisArg, 3)) |
| 8402 : baseClone(value, true); |
| 8403 } |
| 8404 |
| 8405 /** |
| 8406 * Checks if `value` is greater than `other`. |
| 8407 * |
| 8408 * @static |
| 8409 * @memberOf _ |
| 8410 * @category Lang |
| 8411 * @param {*} value The value to compare. |
| 8412 * @param {*} other The other value to compare. |
| 8413 * @returns {boolean} Returns `true` if `value` is greater than `other`, els
e `false`. |
| 8414 * @example |
| 8415 * |
| 8416 * _.gt(3, 1); |
| 8417 * // => true |
| 8418 * |
| 8419 * _.gt(3, 3); |
| 8420 * // => false |
| 8421 * |
| 8422 * _.gt(1, 3); |
| 8423 * // => false |
| 8424 */ |
| 8425 function gt(value, other) { |
| 8426 return value > other; |
| 8427 } |
| 8428 |
| 8429 /** |
| 8430 * Checks if `value` is greater than or equal to `other`. |
| 8431 * |
| 8432 * @static |
| 8433 * @memberOf _ |
| 8434 * @category Lang |
| 8435 * @param {*} value The value to compare. |
| 8436 * @param {*} other The other value to compare. |
| 8437 * @returns {boolean} Returns `true` if `value` is greater than or equal to
`other`, else `false`. |
| 8438 * @example |
| 8439 * |
| 8440 * _.gte(3, 1); |
| 8441 * // => true |
| 8442 * |
| 8443 * _.gte(3, 3); |
| 8444 * // => true |
| 8445 * |
| 8446 * _.gte(1, 3); |
| 8447 * // => false |
| 8448 */ |
| 8449 function gte(value, other) { |
| 8450 return value >= other; |
| 8451 } |
| 8452 |
| 8453 /** |
| 8454 * Checks if `value` is classified as an `arguments` object. |
| 8455 * |
| 8456 * @static |
| 8457 * @memberOf _ |
| 8458 * @category Lang |
| 8459 * @param {*} value The value to check. |
| 8460 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8461 * @example |
| 8462 * |
| 8463 * _.isArguments(function() { return arguments; }()); |
| 8464 * // => true |
| 8465 * |
| 8466 * _.isArguments([1, 2, 3]); |
| 8467 * // => false |
| 8468 */ |
| 8469 function isArguments(value) { |
| 8470 return isObjectLike(value) && isArrayLike(value) && |
| 8471 hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value
, 'callee'); |
| 8472 } |
| 8473 |
| 8474 /** |
| 8475 * Checks if `value` is classified as an `Array` object. |
| 8476 * |
| 8477 * @static |
| 8478 * @memberOf _ |
| 8479 * @category Lang |
| 8480 * @param {*} value The value to check. |
| 8481 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8482 * @example |
| 8483 * |
| 8484 * _.isArray([1, 2, 3]); |
| 8485 * // => true |
| 8486 * |
| 8487 * _.isArray(function() { return arguments; }()); |
| 8488 * // => false |
| 8489 */ |
| 8490 var isArray = nativeIsArray || function(value) { |
| 8491 return isObjectLike(value) && isLength(value.length) && objToString.call(v
alue) == arrayTag; |
| 8492 }; |
| 8493 |
| 8494 /** |
| 8495 * Checks if `value` is classified as a boolean primitive or object. |
| 8496 * |
| 8497 * @static |
| 8498 * @memberOf _ |
| 8499 * @category Lang |
| 8500 * @param {*} value The value to check. |
| 8501 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8502 * @example |
| 8503 * |
| 8504 * _.isBoolean(false); |
| 8505 * // => true |
| 8506 * |
| 8507 * _.isBoolean(null); |
| 8508 * // => false |
| 8509 */ |
| 8510 function isBoolean(value) { |
| 8511 return value === true || value === false || (isObjectLike(value) && objToS
tring.call(value) == boolTag); |
| 8512 } |
| 8513 |
| 8514 /** |
| 8515 * Checks if `value` is classified as a `Date` object. |
| 8516 * |
| 8517 * @static |
| 8518 * @memberOf _ |
| 8519 * @category Lang |
| 8520 * @param {*} value The value to check. |
| 8521 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8522 * @example |
| 8523 * |
| 8524 * _.isDate(new Date); |
| 8525 * // => true |
| 8526 * |
| 8527 * _.isDate('Mon April 23 2012'); |
| 8528 * // => false |
| 8529 */ |
| 8530 function isDate(value) { |
| 8531 return isObjectLike(value) && objToString.call(value) == dateTag; |
| 8532 } |
| 8533 |
| 8534 /** |
| 8535 * Checks if `value` is a DOM element. |
| 8536 * |
| 8537 * @static |
| 8538 * @memberOf _ |
| 8539 * @category Lang |
| 8540 * @param {*} value The value to check. |
| 8541 * @returns {boolean} Returns `true` if `value` is a DOM element, else `fals
e`. |
| 8542 * @example |
| 8543 * |
| 8544 * _.isElement(document.body); |
| 8545 * // => true |
| 8546 * |
| 8547 * _.isElement('<body>'); |
| 8548 * // => false |
| 8549 */ |
| 8550 function isElement(value) { |
| 8551 return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainO
bject(value); |
| 8552 } |
| 8553 |
| 8554 /** |
| 8555 * Checks if `value` is empty. A value is considered empty unless it's an |
| 8556 * `arguments` object, array, string, or jQuery-like collection with a lengt
h |
| 8557 * greater than `0` or an object with own enumerable properties. |
| 8558 * |
| 8559 * @static |
| 8560 * @memberOf _ |
| 8561 * @category Lang |
| 8562 * @param {Array|Object|string} value The value to inspect. |
| 8563 * @returns {boolean} Returns `true` if `value` is empty, else `false`. |
| 8564 * @example |
| 8565 * |
| 8566 * _.isEmpty(null); |
| 8567 * // => true |
| 8568 * |
| 8569 * _.isEmpty(true); |
| 8570 * // => true |
| 8571 * |
| 8572 * _.isEmpty(1); |
| 8573 * // => true |
| 8574 * |
| 8575 * _.isEmpty([1, 2, 3]); |
| 8576 * // => false |
| 8577 * |
| 8578 * _.isEmpty({ 'a': 1 }); |
| 8579 * // => false |
| 8580 */ |
| 8581 function isEmpty(value) { |
| 8582 if (value == null) { |
| 8583 return true; |
| 8584 } |
| 8585 if (isArrayLike(value) && (isArray(value) || isString(value) || isArgument
s(value) || |
| 8586 (isObjectLike(value) && isFunction(value.splice)))) { |
| 8587 return !value.length; |
| 8588 } |
| 8589 return !keys(value).length; |
| 8590 } |
| 8591 |
| 8592 /** |
| 8593 * Performs a deep comparison between two values to determine if they are |
| 8594 * equivalent. If `customizer` is provided it's invoked to compare values. |
| 8595 * If `customizer` returns `undefined` comparisons are handled by the method |
| 8596 * instead. The `customizer` is bound to `thisArg` and invoked with up to |
| 8597 * three arguments: (value, other [, index|key]). |
| 8598 * |
| 8599 * **Note:** This method supports comparing arrays, booleans, `Date` objects
, |
| 8600 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
| 8601 * their own, not inherited, enumerable properties. Functions and DOM nodes |
| 8602 * are **not** supported. Provide a customizer function to extend support |
| 8603 * for comparing other values. |
| 8604 * |
| 8605 * @static |
| 8606 * @memberOf _ |
| 8607 * @alias eq |
| 8608 * @category Lang |
| 8609 * @param {*} value The value to compare. |
| 8610 * @param {*} other The other value to compare. |
| 8611 * @param {Function} [customizer] The function to customize value comparison
s. |
| 8612 * @param {*} [thisArg] The `this` binding of `customizer`. |
| 8613 * @returns {boolean} Returns `true` if the values are equivalent, else `fal
se`. |
| 8614 * @example |
| 8615 * |
| 8616 * var object = { 'user': 'fred' }; |
| 8617 * var other = { 'user': 'fred' }; |
| 8618 * |
| 8619 * object == other; |
| 8620 * // => false |
| 8621 * |
| 8622 * _.isEqual(object, other); |
| 8623 * // => true |
| 8624 * |
| 8625 * // using a customizer callback |
| 8626 * var array = ['hello', 'goodbye']; |
| 8627 * var other = ['hi', 'goodbye']; |
| 8628 * |
| 8629 * _.isEqual(array, other, function(value, other) { |
| 8630 * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { |
| 8631 * return true; |
| 8632 * } |
| 8633 * }); |
| 8634 * // => true |
| 8635 */ |
| 8636 function isEqual(value, other, customizer, thisArg) { |
| 8637 customizer = typeof customizer == 'function' ? bindCallback(customizer, th
isArg, 3) : undefined; |
| 8638 var result = customizer ? customizer(value, other) : undefined; |
| 8639 return result === undefined ? baseIsEqual(value, other, customizer) : !!r
esult; |
| 8640 } |
| 8641 |
| 8642 /** |
| 8643 * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceErr
or`, |
| 8644 * `SyntaxError`, `TypeError`, or `URIError` object. |
| 8645 * |
| 8646 * @static |
| 8647 * @memberOf _ |
| 8648 * @category Lang |
| 8649 * @param {*} value The value to check. |
| 8650 * @returns {boolean} Returns `true` if `value` is an error object, else `fa
lse`. |
| 8651 * @example |
| 8652 * |
| 8653 * _.isError(new Error); |
| 8654 * // => true |
| 8655 * |
| 8656 * _.isError(Error); |
| 8657 * // => false |
| 8658 */ |
| 8659 function isError(value) { |
| 8660 return isObjectLike(value) && typeof value.message == 'string' && objToStr
ing.call(value) == errorTag; |
| 8661 } |
| 8662 |
| 8663 /** |
| 8664 * Checks if `value` is a finite primitive number. |
| 8665 * |
| 8666 * **Note:** This method is based on [`Number.isFinite`](http://ecma-interna
tional.org/ecma-262/6.0/#sec-number.isfinite). |
| 8667 * |
| 8668 * @static |
| 8669 * @memberOf _ |
| 8670 * @category Lang |
| 8671 * @param {*} value The value to check. |
| 8672 * @returns {boolean} Returns `true` if `value` is a finite number, else `fa
lse`. |
| 8673 * @example |
| 8674 * |
| 8675 * _.isFinite(10); |
| 8676 * // => true |
| 8677 * |
| 8678 * _.isFinite('10'); |
| 8679 * // => false |
| 8680 * |
| 8681 * _.isFinite(true); |
| 8682 * // => false |
| 8683 * |
| 8684 * _.isFinite(Object(10)); |
| 8685 * // => false |
| 8686 * |
| 8687 * _.isFinite(Infinity); |
| 8688 * // => false |
| 8689 */ |
| 8690 function isFinite(value) { |
| 8691 return typeof value == 'number' && nativeIsFinite(value); |
| 8692 } |
| 8693 |
| 8694 /** |
| 8695 * Checks if `value` is classified as a `Function` object. |
| 8696 * |
| 8697 * @static |
| 8698 * @memberOf _ |
| 8699 * @category Lang |
| 8700 * @param {*} value The value to check. |
| 8701 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8702 * @example |
| 8703 * |
| 8704 * _.isFunction(_); |
| 8705 * // => true |
| 8706 * |
| 8707 * _.isFunction(/abc/); |
| 8708 * // => false |
| 8709 */ |
| 8710 function isFunction(value) { |
| 8711 // The use of `Object#toString` avoids issues with the `typeof` operator |
| 8712 // in older versions of Chrome and Safari which return 'function' for rege
xes |
| 8713 // and Safari 8 which returns 'object' for typed array constructors. |
| 8714 return isObject(value) && objToString.call(value) == funcTag; |
| 8715 } |
| 8716 |
| 8717 /** |
| 8718 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `O
bject`. |
| 8719 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new Stri
ng('')`) |
| 8720 * |
| 8721 * @static |
| 8722 * @memberOf _ |
| 8723 * @category Lang |
| 8724 * @param {*} value The value to check. |
| 8725 * @returns {boolean} Returns `true` if `value` is an object, else `false`. |
| 8726 * @example |
| 8727 * |
| 8728 * _.isObject({}); |
| 8729 * // => true |
| 8730 * |
| 8731 * _.isObject([1, 2, 3]); |
| 8732 * // => true |
| 8733 * |
| 8734 * _.isObject(1); |
| 8735 * // => false |
| 8736 */ |
| 8737 function isObject(value) { |
| 8738 // Avoid a V8 JIT bug in Chrome 19-20. |
| 8739 // See https://code.google.com/p/v8/issues/detail?id=2291 for more details
. |
| 8740 var type = typeof value; |
| 8741 return !!value && (type == 'object' || type == 'function'); |
| 8742 } |
| 8743 |
| 8744 /** |
| 8745 * Performs a deep comparison between `object` and `source` to determine if |
| 8746 * `object` contains equivalent property values. If `customizer` is provided |
| 8747 * it's invoked to compare values. If `customizer` returns `undefined` |
| 8748 * comparisons are handled by the method instead. The `customizer` is bound |
| 8749 * to `thisArg` and invoked with three arguments: (value, other, index|key). |
| 8750 * |
| 8751 * **Note:** This method supports comparing properties of arrays, booleans, |
| 8752 * `Date` objects, numbers, `Object` objects, regexes, and strings. Function
s |
| 8753 * and DOM nodes are **not** supported. Provide a customizer function to ext
end |
| 8754 * support for comparing other values. |
| 8755 * |
| 8756 * @static |
| 8757 * @memberOf _ |
| 8758 * @category Lang |
| 8759 * @param {Object} object The object to inspect. |
| 8760 * @param {Object} source The object of property values to match. |
| 8761 * @param {Function} [customizer] The function to customize value comparison
s. |
| 8762 * @param {*} [thisArg] The `this` binding of `customizer`. |
| 8763 * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
| 8764 * @example |
| 8765 * |
| 8766 * var object = { 'user': 'fred', 'age': 40 }; |
| 8767 * |
| 8768 * _.isMatch(object, { 'age': 40 }); |
| 8769 * // => true |
| 8770 * |
| 8771 * _.isMatch(object, { 'age': 36 }); |
| 8772 * // => false |
| 8773 * |
| 8774 * // using a customizer callback |
| 8775 * var object = { 'greeting': 'hello' }; |
| 8776 * var source = { 'greeting': 'hi' }; |
| 8777 * |
| 8778 * _.isMatch(object, source, function(value, other) { |
| 8779 * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)
|| undefined; |
| 8780 * }); |
| 8781 * // => true |
| 8782 */ |
| 8783 function isMatch(object, source, customizer, thisArg) { |
| 8784 customizer = typeof customizer == 'function' ? bindCallback(customizer, th
isArg, 3) : undefined; |
| 8785 return baseIsMatch(object, getMatchData(source), customizer); |
| 8786 } |
| 8787 |
| 8788 /** |
| 8789 * Checks if `value` is `NaN`. |
| 8790 * |
| 8791 * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/
#x15.1.2.4) |
| 8792 * which returns `true` for `undefined` and other non-numeric values. |
| 8793 * |
| 8794 * @static |
| 8795 * @memberOf _ |
| 8796 * @category Lang |
| 8797 * @param {*} value The value to check. |
| 8798 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. |
| 8799 * @example |
| 8800 * |
| 8801 * _.isNaN(NaN); |
| 8802 * // => true |
| 8803 * |
| 8804 * _.isNaN(new Number(NaN)); |
| 8805 * // => true |
| 8806 * |
| 8807 * isNaN(undefined); |
| 8808 * // => true |
| 8809 * |
| 8810 * _.isNaN(undefined); |
| 8811 * // => false |
| 8812 */ |
| 8813 function isNaN(value) { |
| 8814 // An `NaN` primitive is the only value that is not equal to itself. |
| 8815 // Perform the `toStringTag` check first to avoid errors with some host ob
jects in IE. |
| 8816 return isNumber(value) && value != +value; |
| 8817 } |
| 8818 |
| 8819 /** |
| 8820 * Checks if `value` is a native function. |
| 8821 * |
| 8822 * @static |
| 8823 * @memberOf _ |
| 8824 * @category Lang |
| 8825 * @param {*} value The value to check. |
| 8826 * @returns {boolean} Returns `true` if `value` is a native function, else `
false`. |
| 8827 * @example |
| 8828 * |
| 8829 * _.isNative(Array.prototype.push); |
| 8830 * // => true |
| 8831 * |
| 8832 * _.isNative(_); |
| 8833 * // => false |
| 8834 */ |
| 8835 function isNative(value) { |
| 8836 if (value == null) { |
| 8837 return false; |
| 8838 } |
| 8839 if (isFunction(value)) { |
| 8840 return reIsNative.test(fnToString.call(value)); |
| 8841 } |
| 8842 return isObjectLike(value) && reIsHostCtor.test(value); |
| 8843 } |
| 8844 |
| 8845 /** |
| 8846 * Checks if `value` is `null`. |
| 8847 * |
| 8848 * @static |
| 8849 * @memberOf _ |
| 8850 * @category Lang |
| 8851 * @param {*} value The value to check. |
| 8852 * @returns {boolean} Returns `true` if `value` is `null`, else `false`. |
| 8853 * @example |
| 8854 * |
| 8855 * _.isNull(null); |
| 8856 * // => true |
| 8857 * |
| 8858 * _.isNull(void 0); |
| 8859 * // => false |
| 8860 */ |
| 8861 function isNull(value) { |
| 8862 return value === null; |
| 8863 } |
| 8864 |
| 8865 /** |
| 8866 * Checks if `value` is classified as a `Number` primitive or object. |
| 8867 * |
| 8868 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classi
fied |
| 8869 * as numbers, use the `_.isFinite` method. |
| 8870 * |
| 8871 * @static |
| 8872 * @memberOf _ |
| 8873 * @category Lang |
| 8874 * @param {*} value The value to check. |
| 8875 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8876 * @example |
| 8877 * |
| 8878 * _.isNumber(8.4); |
| 8879 * // => true |
| 8880 * |
| 8881 * _.isNumber(NaN); |
| 8882 * // => true |
| 8883 * |
| 8884 * _.isNumber('8.4'); |
| 8885 * // => false |
| 8886 */ |
| 8887 function isNumber(value) { |
| 8888 return typeof value == 'number' || (isObjectLike(value) && objToString.cal
l(value) == numberTag); |
| 8889 } |
| 8890 |
| 8891 /** |
| 8892 * Checks if `value` is a plain object, that is, an object created by the |
| 8893 * `Object` constructor or one with a `[[Prototype]]` of `null`. |
| 8894 * |
| 8895 * **Note:** This method assumes objects created by the `Object` constructor |
| 8896 * have no inherited enumerable properties. |
| 8897 * |
| 8898 * @static |
| 8899 * @memberOf _ |
| 8900 * @category Lang |
| 8901 * @param {*} value The value to check. |
| 8902 * @returns {boolean} Returns `true` if `value` is a plain object, else `fal
se`. |
| 8903 * @example |
| 8904 * |
| 8905 * function Foo() { |
| 8906 * this.a = 1; |
| 8907 * } |
| 8908 * |
| 8909 * _.isPlainObject(new Foo); |
| 8910 * // => false |
| 8911 * |
| 8912 * _.isPlainObject([1, 2, 3]); |
| 8913 * // => false |
| 8914 * |
| 8915 * _.isPlainObject({ 'x': 0, 'y': 0 }); |
| 8916 * // => true |
| 8917 * |
| 8918 * _.isPlainObject(Object.create(null)); |
| 8919 * // => true |
| 8920 */ |
| 8921 function isPlainObject(value) { |
| 8922 var Ctor; |
| 8923 |
| 8924 // Exit early for non `Object` objects. |
| 8925 if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isAr
guments(value)) || |
| 8926 (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.construct
or, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { |
| 8927 return false; |
| 8928 } |
| 8929 // IE < 9 iterates inherited properties before own properties. If the firs
t |
| 8930 // iterated property is an object's own property then there are no inherit
ed |
| 8931 // enumerable properties. |
| 8932 var result; |
| 8933 // In most environments an object's own properties are iterated before |
| 8934 // its inherited properties. If the last iterated property is an object's |
| 8935 // own property then there are no inherited enumerable properties. |
| 8936 baseForIn(value, function(subValue, key) { |
| 8937 result = key; |
| 8938 }); |
| 8939 return result === undefined || hasOwnProperty.call(value, result); |
| 8940 } |
| 8941 |
| 8942 /** |
| 8943 * Checks if `value` is classified as a `RegExp` object. |
| 8944 * |
| 8945 * @static |
| 8946 * @memberOf _ |
| 8947 * @category Lang |
| 8948 * @param {*} value The value to check. |
| 8949 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8950 * @example |
| 8951 * |
| 8952 * _.isRegExp(/abc/); |
| 8953 * // => true |
| 8954 * |
| 8955 * _.isRegExp('/abc/'); |
| 8956 * // => false |
| 8957 */ |
| 8958 function isRegExp(value) { |
| 8959 return isObject(value) && objToString.call(value) == regexpTag; |
| 8960 } |
| 8961 |
| 8962 /** |
| 8963 * Checks if `value` is classified as a `String` primitive or object. |
| 8964 * |
| 8965 * @static |
| 8966 * @memberOf _ |
| 8967 * @category Lang |
| 8968 * @param {*} value The value to check. |
| 8969 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8970 * @example |
| 8971 * |
| 8972 * _.isString('abc'); |
| 8973 * // => true |
| 8974 * |
| 8975 * _.isString(1); |
| 8976 * // => false |
| 8977 */ |
| 8978 function isString(value) { |
| 8979 return typeof value == 'string' || (isObjectLike(value) && objToString.cal
l(value) == stringTag); |
| 8980 } |
| 8981 |
| 8982 /** |
| 8983 * Checks if `value` is classified as a typed array. |
| 8984 * |
| 8985 * @static |
| 8986 * @memberOf _ |
| 8987 * @category Lang |
| 8988 * @param {*} value The value to check. |
| 8989 * @returns {boolean} Returns `true` if `value` is correctly classified, els
e `false`. |
| 8990 * @example |
| 8991 * |
| 8992 * _.isTypedArray(new Uint8Array); |
| 8993 * // => true |
| 8994 * |
| 8995 * _.isTypedArray([]); |
| 8996 * // => false |
| 8997 */ |
| 8998 function isTypedArray(value) { |
| 8999 return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[o
bjToString.call(value)]; |
| 9000 } |
| 9001 |
| 9002 /** |
| 9003 * Checks if `value` is `undefined`. |
| 9004 * |
| 9005 * @static |
| 9006 * @memberOf _ |
| 9007 * @category Lang |
| 9008 * @param {*} value The value to check. |
| 9009 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`
. |
| 9010 * @example |
| 9011 * |
| 9012 * _.isUndefined(void 0); |
| 9013 * // => true |
| 9014 * |
| 9015 * _.isUndefined(null); |
| 9016 * // => false |
| 9017 */ |
| 9018 function isUndefined(value) { |
| 9019 return value === undefined; |
| 9020 } |
| 9021 |
| 9022 /** |
| 9023 * Checks if `value` is less than `other`. |
| 9024 * |
| 9025 * @static |
| 9026 * @memberOf _ |
| 9027 * @category Lang |
| 9028 * @param {*} value The value to compare. |
| 9029 * @param {*} other The other value to compare. |
| 9030 * @returns {boolean} Returns `true` if `value` is less than `other`, else `
false`. |
| 9031 * @example |
| 9032 * |
| 9033 * _.lt(1, 3); |
| 9034 * // => true |
| 9035 * |
| 9036 * _.lt(3, 3); |
| 9037 * // => false |
| 9038 * |
| 9039 * _.lt(3, 1); |
| 9040 * // => false |
| 9041 */ |
| 9042 function lt(value, other) { |
| 9043 return value < other; |
| 9044 } |
| 9045 |
| 9046 /** |
| 9047 * Checks if `value` is less than or equal to `other`. |
| 9048 * |
| 9049 * @static |
| 9050 * @memberOf _ |
| 9051 * @category Lang |
| 9052 * @param {*} value The value to compare. |
| 9053 * @param {*} other The other value to compare. |
| 9054 * @returns {boolean} Returns `true` if `value` is less than or equal to `ot
her`, else `false`. |
| 9055 * @example |
| 9056 * |
| 9057 * _.lte(1, 3); |
| 9058 * // => true |
| 9059 * |
| 9060 * _.lte(3, 3); |
| 9061 * // => true |
| 9062 * |
| 9063 * _.lte(3, 1); |
| 9064 * // => false |
| 9065 */ |
| 9066 function lte(value, other) { |
| 9067 return value <= other; |
| 9068 } |
| 9069 |
| 9070 /** |
| 9071 * Converts `value` to an array. |
| 9072 * |
| 9073 * @static |
| 9074 * @memberOf _ |
| 9075 * @category Lang |
| 9076 * @param {*} value The value to convert. |
| 9077 * @returns {Array} Returns the converted array. |
| 9078 * @example |
| 9079 * |
| 9080 * (function() { |
| 9081 * return _.toArray(arguments).slice(1); |
| 9082 * }(1, 2, 3)); |
| 9083 * // => [2, 3] |
| 9084 */ |
| 9085 function toArray(value) { |
| 9086 var length = value ? getLength(value) : 0; |
| 9087 if (!isLength(length)) { |
| 9088 return values(value); |
| 9089 } |
| 9090 if (!length) { |
| 9091 return []; |
| 9092 } |
| 9093 return arrayCopy(value); |
| 9094 } |
| 9095 |
| 9096 /** |
| 9097 * Converts `value` to a plain object flattening inherited enumerable |
| 9098 * properties of `value` to own properties of the plain object. |
| 9099 * |
| 9100 * @static |
| 9101 * @memberOf _ |
| 9102 * @category Lang |
| 9103 * @param {*} value The value to convert. |
| 9104 * @returns {Object} Returns the converted plain object. |
| 9105 * @example |
| 9106 * |
| 9107 * function Foo() { |
| 9108 * this.b = 2; |
| 9109 * } |
| 9110 * |
| 9111 * Foo.prototype.c = 3; |
| 9112 * |
| 9113 * _.assign({ 'a': 1 }, new Foo); |
| 9114 * // => { 'a': 1, 'b': 2 } |
| 9115 * |
| 9116 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); |
| 9117 * // => { 'a': 1, 'b': 2, 'c': 3 } |
| 9118 */ |
| 9119 function toPlainObject(value) { |
| 9120 return baseCopy(value, keysIn(value)); |
| 9121 } |
| 9122 |
| 9123 /*------------------------------------------------------------------------*/ |
| 9124 |
| 9125 /** |
| 9126 * Recursively merges own enumerable properties of the source object(s), tha
t |
| 9127 * don't resolve to `undefined` into the destination object. Subsequent sour
ces |
| 9128 * overwrite property assignments of previous sources. If `customizer` is |
| 9129 * provided it's invoked to produce the merged values of the destination and |
| 9130 * source properties. If `customizer` returns `undefined` merging is handled |
| 9131 * by the method instead. The `customizer` is bound to `thisArg` and invoked |
| 9132 * with five arguments: (objectValue, sourceValue, key, object, source). |
| 9133 * |
| 9134 * @static |
| 9135 * @memberOf _ |
| 9136 * @category Object |
| 9137 * @param {Object} object The destination object. |
| 9138 * @param {...Object} [sources] The source objects. |
| 9139 * @param {Function} [customizer] The function to customize assigned values. |
| 9140 * @param {*} [thisArg] The `this` binding of `customizer`. |
| 9141 * @returns {Object} Returns `object`. |
| 9142 * @example |
| 9143 * |
| 9144 * var users = { |
| 9145 * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] |
| 9146 * }; |
| 9147 * |
| 9148 * var ages = { |
| 9149 * 'data': [{ 'age': 36 }, { 'age': 40 }] |
| 9150 * }; |
| 9151 * |
| 9152 * _.merge(users, ages); |
| 9153 * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age'
: 40 }] } |
| 9154 * |
| 9155 * // using a customizer callback |
| 9156 * var object = { |
| 9157 * 'fruits': ['apple'], |
| 9158 * 'vegetables': ['beet'] |
| 9159 * }; |
| 9160 * |
| 9161 * var other = { |
| 9162 * 'fruits': ['banana'], |
| 9163 * 'vegetables': ['carrot'] |
| 9164 * }; |
| 9165 * |
| 9166 * _.merge(object, other, function(a, b) { |
| 9167 * if (_.isArray(a)) { |
| 9168 * return a.concat(b); |
| 9169 * } |
| 9170 * }); |
| 9171 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } |
| 9172 */ |
| 9173 var merge = createAssigner(baseMerge); |
| 9174 |
| 9175 /** |
| 9176 * Assigns own enumerable properties of source object(s) to the destination |
| 9177 * object. Subsequent sources overwrite property assignments of previous sou
rces. |
| 9178 * If `customizer` is provided it's invoked to produce the assigned values. |
| 9179 * The `customizer` is bound to `thisArg` and invoked with five arguments: |
| 9180 * (objectValue, sourceValue, key, object, source). |
| 9181 * |
| 9182 * **Note:** This method mutates `object` and is based on |
| 9183 * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.
assign). |
| 9184 * |
| 9185 * @static |
| 9186 * @memberOf _ |
| 9187 * @alias extend |
| 9188 * @category Object |
| 9189 * @param {Object} object The destination object. |
| 9190 * @param {...Object} [sources] The source objects. |
| 9191 * @param {Function} [customizer] The function to customize assigned values. |
| 9192 * @param {*} [thisArg] The `this` binding of `customizer`. |
| 9193 * @returns {Object} Returns `object`. |
| 9194 * @example |
| 9195 * |
| 9196 * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); |
| 9197 * // => { 'user': 'fred', 'age': 40 } |
| 9198 * |
| 9199 * // using a customizer callback |
| 9200 * var defaults = _.partialRight(_.assign, function(value, other) { |
| 9201 * return _.isUndefined(value) ? other : value; |
| 9202 * }); |
| 9203 * |
| 9204 * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); |
| 9205 * // => { 'user': 'barney', 'age': 36 } |
| 9206 */ |
| 9207 var assign = createAssigner(function(object, source, customizer) { |
| 9208 return customizer |
| 9209 ? assignWith(object, source, customizer) |
| 9210 : baseAssign(object, source); |
| 9211 }); |
| 9212 |
| 9213 /** |
| 9214 * Creates an object that inherits from the given `prototype` object. If a |
| 9215 * `properties` object is provided its own enumerable properties are assigne
d |
| 9216 * to the created object. |
| 9217 * |
| 9218 * @static |
| 9219 * @memberOf _ |
| 9220 * @category Object |
| 9221 * @param {Object} prototype The object to inherit from. |
| 9222 * @param {Object} [properties] The properties to assign to the object. |
| 9223 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 9224 * @returns {Object} Returns the new object. |
| 9225 * @example |
| 9226 * |
| 9227 * function Shape() { |
| 9228 * this.x = 0; |
| 9229 * this.y = 0; |
| 9230 * } |
| 9231 * |
| 9232 * function Circle() { |
| 9233 * Shape.call(this); |
| 9234 * } |
| 9235 * |
| 9236 * Circle.prototype = _.create(Shape.prototype, { |
| 9237 * 'constructor': Circle |
| 9238 * }); |
| 9239 * |
| 9240 * var circle = new Circle; |
| 9241 * circle instanceof Circle; |
| 9242 * // => true |
| 9243 * |
| 9244 * circle instanceof Shape; |
| 9245 * // => true |
| 9246 */ |
| 9247 function create(prototype, properties, guard) { |
| 9248 var result = baseCreate(prototype); |
| 9249 if (guard && isIterateeCall(prototype, properties, guard)) { |
| 9250 properties = undefined; |
| 9251 } |
| 9252 return properties ? baseAssign(result, properties) : result; |
| 9253 } |
| 9254 |
| 9255 /** |
| 9256 * Assigns own enumerable properties of source object(s) to the destination |
| 9257 * object for all destination properties that resolve to `undefined`. Once a |
| 9258 * property is set, additional values of the same property are ignored. |
| 9259 * |
| 9260 * **Note:** This method mutates `object`. |
| 9261 * |
| 9262 * @static |
| 9263 * @memberOf _ |
| 9264 * @category Object |
| 9265 * @param {Object} object The destination object. |
| 9266 * @param {...Object} [sources] The source objects. |
| 9267 * @returns {Object} Returns `object`. |
| 9268 * @example |
| 9269 * |
| 9270 * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); |
| 9271 * // => { 'user': 'barney', 'age': 36 } |
| 9272 */ |
| 9273 var defaults = createDefaults(assign, assignDefaults); |
| 9274 |
| 9275 /** |
| 9276 * This method is like `_.defaults` except that it recursively assigns |
| 9277 * default properties. |
| 9278 * |
| 9279 * **Note:** This method mutates `object`. |
| 9280 * |
| 9281 * @static |
| 9282 * @memberOf _ |
| 9283 * @category Object |
| 9284 * @param {Object} object The destination object. |
| 9285 * @param {...Object} [sources] The source objects. |
| 9286 * @returns {Object} Returns `object`. |
| 9287 * @example |
| 9288 * |
| 9289 * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fre
d', 'age': 36 } }); |
| 9290 * // => { 'user': { 'name': 'barney', 'age': 36 } } |
| 9291 * |
| 9292 */ |
| 9293 var defaultsDeep = createDefaults(merge, mergeDefaults); |
| 9294 |
| 9295 /** |
| 9296 * This method is like `_.find` except that it returns the key of the first |
| 9297 * element `predicate` returns truthy for instead of the element itself. |
| 9298 * |
| 9299 * If a property name is provided for `predicate` the created `_.property` |
| 9300 * style callback returns the property value of the given element. |
| 9301 * |
| 9302 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 9303 * style callback returns `true` for elements that have a matching property |
| 9304 * value, else `false`. |
| 9305 * |
| 9306 * If an object is provided for `predicate` the created `_.matches` style |
| 9307 * callback returns `true` for elements that have the properties of the give
n |
| 9308 * object, else `false`. |
| 9309 * |
| 9310 * @static |
| 9311 * @memberOf _ |
| 9312 * @category Object |
| 9313 * @param {Object} object The object to search. |
| 9314 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 9315 * per iteration. |
| 9316 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 9317 * @returns {string|undefined} Returns the key of the matched element, else
`undefined`. |
| 9318 * @example |
| 9319 * |
| 9320 * var users = { |
| 9321 * 'barney': { 'age': 36, 'active': true }, |
| 9322 * 'fred': { 'age': 40, 'active': false }, |
| 9323 * 'pebbles': { 'age': 1, 'active': true } |
| 9324 * }; |
| 9325 * |
| 9326 * _.findKey(users, function(chr) { |
| 9327 * return chr.age < 40; |
| 9328 * }); |
| 9329 * // => 'barney' (iteration order is not guaranteed) |
| 9330 * |
| 9331 * // using the `_.matches` callback shorthand |
| 9332 * _.findKey(users, { 'age': 1, 'active': true }); |
| 9333 * // => 'pebbles' |
| 9334 * |
| 9335 * // using the `_.matchesProperty` callback shorthand |
| 9336 * _.findKey(users, 'active', false); |
| 9337 * // => 'fred' |
| 9338 * |
| 9339 * // using the `_.property` callback shorthand |
| 9340 * _.findKey(users, 'active'); |
| 9341 * // => 'barney' |
| 9342 */ |
| 9343 var findKey = createFindKey(baseForOwn); |
| 9344 |
| 9345 /** |
| 9346 * This method is like `_.findKey` except that it iterates over elements of |
| 9347 * a collection in the opposite order. |
| 9348 * |
| 9349 * If a property name is provided for `predicate` the created `_.property` |
| 9350 * style callback returns the property value of the given element. |
| 9351 * |
| 9352 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 9353 * style callback returns `true` for elements that have a matching property |
| 9354 * value, else `false`. |
| 9355 * |
| 9356 * If an object is provided for `predicate` the created `_.matches` style |
| 9357 * callback returns `true` for elements that have the properties of the give
n |
| 9358 * object, else `false`. |
| 9359 * |
| 9360 * @static |
| 9361 * @memberOf _ |
| 9362 * @category Object |
| 9363 * @param {Object} object The object to search. |
| 9364 * @param {Function|Object|string} [predicate=_.identity] The function invok
ed |
| 9365 * per iteration. |
| 9366 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 9367 * @returns {string|undefined} Returns the key of the matched element, else
`undefined`. |
| 9368 * @example |
| 9369 * |
| 9370 * var users = { |
| 9371 * 'barney': { 'age': 36, 'active': true }, |
| 9372 * 'fred': { 'age': 40, 'active': false }, |
| 9373 * 'pebbles': { 'age': 1, 'active': true } |
| 9374 * }; |
| 9375 * |
| 9376 * _.findLastKey(users, function(chr) { |
| 9377 * return chr.age < 40; |
| 9378 * }); |
| 9379 * // => returns `pebbles` assuming `_.findKey` returns `barney` |
| 9380 * |
| 9381 * // using the `_.matches` callback shorthand |
| 9382 * _.findLastKey(users, { 'age': 36, 'active': true }); |
| 9383 * // => 'barney' |
| 9384 * |
| 9385 * // using the `_.matchesProperty` callback shorthand |
| 9386 * _.findLastKey(users, 'active', false); |
| 9387 * // => 'fred' |
| 9388 * |
| 9389 * // using the `_.property` callback shorthand |
| 9390 * _.findLastKey(users, 'active'); |
| 9391 * // => 'pebbles' |
| 9392 */ |
| 9393 var findLastKey = createFindKey(baseForOwnRight); |
| 9394 |
| 9395 /** |
| 9396 * Iterates over own and inherited enumerable properties of an object invoki
ng |
| 9397 * `iteratee` for each property. The `iteratee` is bound to `thisArg` and in
voked |
| 9398 * with three arguments: (value, key, object). Iteratee functions may exit |
| 9399 * iteration early by explicitly returning `false`. |
| 9400 * |
| 9401 * @static |
| 9402 * @memberOf _ |
| 9403 * @category Object |
| 9404 * @param {Object} object The object to iterate over. |
| 9405 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 9406 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 9407 * @returns {Object} Returns `object`. |
| 9408 * @example |
| 9409 * |
| 9410 * function Foo() { |
| 9411 * this.a = 1; |
| 9412 * this.b = 2; |
| 9413 * } |
| 9414 * |
| 9415 * Foo.prototype.c = 3; |
| 9416 * |
| 9417 * _.forIn(new Foo, function(value, key) { |
| 9418 * console.log(key); |
| 9419 * }); |
| 9420 * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) |
| 9421 */ |
| 9422 var forIn = createForIn(baseFor); |
| 9423 |
| 9424 /** |
| 9425 * This method is like `_.forIn` except that it iterates over properties of |
| 9426 * `object` in the opposite order. |
| 9427 * |
| 9428 * @static |
| 9429 * @memberOf _ |
| 9430 * @category Object |
| 9431 * @param {Object} object The object to iterate over. |
| 9432 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 9433 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 9434 * @returns {Object} Returns `object`. |
| 9435 * @example |
| 9436 * |
| 9437 * function Foo() { |
| 9438 * this.a = 1; |
| 9439 * this.b = 2; |
| 9440 * } |
| 9441 * |
| 9442 * Foo.prototype.c = 3; |
| 9443 * |
| 9444 * _.forInRight(new Foo, function(value, key) { |
| 9445 * console.log(key); |
| 9446 * }); |
| 9447 * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' |
| 9448 */ |
| 9449 var forInRight = createForIn(baseForRight); |
| 9450 |
| 9451 /** |
| 9452 * Iterates over own enumerable properties of an object invoking `iteratee` |
| 9453 * for each property. The `iteratee` is bound to `thisArg` and invoked with |
| 9454 * three arguments: (value, key, object). Iteratee functions may exit iterat
ion |
| 9455 * early by explicitly returning `false`. |
| 9456 * |
| 9457 * @static |
| 9458 * @memberOf _ |
| 9459 * @category Object |
| 9460 * @param {Object} object The object to iterate over. |
| 9461 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 9462 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 9463 * @returns {Object} Returns `object`. |
| 9464 * @example |
| 9465 * |
| 9466 * function Foo() { |
| 9467 * this.a = 1; |
| 9468 * this.b = 2; |
| 9469 * } |
| 9470 * |
| 9471 * Foo.prototype.c = 3; |
| 9472 * |
| 9473 * _.forOwn(new Foo, function(value, key) { |
| 9474 * console.log(key); |
| 9475 * }); |
| 9476 * // => logs 'a' and 'b' (iteration order is not guaranteed) |
| 9477 */ |
| 9478 var forOwn = createForOwn(baseForOwn); |
| 9479 |
| 9480 /** |
| 9481 * This method is like `_.forOwn` except that it iterates over properties of |
| 9482 * `object` in the opposite order. |
| 9483 * |
| 9484 * @static |
| 9485 * @memberOf _ |
| 9486 * @category Object |
| 9487 * @param {Object} object The object to iterate over. |
| 9488 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 9489 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 9490 * @returns {Object} Returns `object`. |
| 9491 * @example |
| 9492 * |
| 9493 * function Foo() { |
| 9494 * this.a = 1; |
| 9495 * this.b = 2; |
| 9496 * } |
| 9497 * |
| 9498 * Foo.prototype.c = 3; |
| 9499 * |
| 9500 * _.forOwnRight(new Foo, function(value, key) { |
| 9501 * console.log(key); |
| 9502 * }); |
| 9503 * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' |
| 9504 */ |
| 9505 var forOwnRight = createForOwn(baseForOwnRight); |
| 9506 |
| 9507 /** |
| 9508 * Creates an array of function property names from all enumerable propertie
s, |
| 9509 * own and inherited, of `object`. |
| 9510 * |
| 9511 * @static |
| 9512 * @memberOf _ |
| 9513 * @alias methods |
| 9514 * @category Object |
| 9515 * @param {Object} object The object to inspect. |
| 9516 * @returns {Array} Returns the new array of property names. |
| 9517 * @example |
| 9518 * |
| 9519 * _.functions(_); |
| 9520 * // => ['after', 'ary', 'assign', ...] |
| 9521 */ |
| 9522 function functions(object) { |
| 9523 return baseFunctions(object, keysIn(object)); |
| 9524 } |
| 9525 |
| 9526 /** |
| 9527 * Gets the property value at `path` of `object`. If the resolved value is |
| 9528 * `undefined` the `defaultValue` is used in its place. |
| 9529 * |
| 9530 * @static |
| 9531 * @memberOf _ |
| 9532 * @category Object |
| 9533 * @param {Object} object The object to query. |
| 9534 * @param {Array|string} path The path of the property to get. |
| 9535 * @param {*} [defaultValue] The value returned if the resolved value is `un
defined`. |
| 9536 * @returns {*} Returns the resolved value. |
| 9537 * @example |
| 9538 * |
| 9539 * var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
| 9540 * |
| 9541 * _.get(object, 'a[0].b.c'); |
| 9542 * // => 3 |
| 9543 * |
| 9544 * _.get(object, ['a', '0', 'b', 'c']); |
| 9545 * // => 3 |
| 9546 * |
| 9547 * _.get(object, 'a.b.c', 'default'); |
| 9548 * // => 'default' |
| 9549 */ |
| 9550 function get(object, path, defaultValue) { |
| 9551 var result = object == null ? undefined : baseGet(object, toPath(path), (p
ath + '')); |
| 9552 return result === undefined ? defaultValue : result; |
| 9553 } |
| 9554 |
| 9555 /** |
| 9556 * Checks if `path` is a direct property. |
| 9557 * |
| 9558 * @static |
| 9559 * @memberOf _ |
| 9560 * @category Object |
| 9561 * @param {Object} object The object to query. |
| 9562 * @param {Array|string} path The path to check. |
| 9563 * @returns {boolean} Returns `true` if `path` is a direct property, else `f
alse`. |
| 9564 * @example |
| 9565 * |
| 9566 * var object = { 'a': { 'b': { 'c': 3 } } }; |
| 9567 * |
| 9568 * _.has(object, 'a'); |
| 9569 * // => true |
| 9570 * |
| 9571 * _.has(object, 'a.b.c'); |
| 9572 * // => true |
| 9573 * |
| 9574 * _.has(object, ['a', 'b', 'c']); |
| 9575 * // => true |
| 9576 */ |
| 9577 function has(object, path) { |
| 9578 if (object == null) { |
| 9579 return false; |
| 9580 } |
| 9581 var result = hasOwnProperty.call(object, path); |
| 9582 if (!result && !isKey(path)) { |
| 9583 path = toPath(path); |
| 9584 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0,
-1)); |
| 9585 if (object == null) { |
| 9586 return false; |
| 9587 } |
| 9588 path = last(path); |
| 9589 result = hasOwnProperty.call(object, path); |
| 9590 } |
| 9591 return result || (isLength(object.length) && isIndex(path, object.length)
&& |
| 9592 (isArray(object) || isArguments(object))); |
| 9593 } |
| 9594 |
| 9595 /** |
| 9596 * Creates an object composed of the inverted keys and values of `object`. |
| 9597 * If `object` contains duplicate values, subsequent values overwrite proper
ty |
| 9598 * assignments of previous values unless `multiValue` is `true`. |
| 9599 * |
| 9600 * @static |
| 9601 * @memberOf _ |
| 9602 * @category Object |
| 9603 * @param {Object} object The object to invert. |
| 9604 * @param {boolean} [multiValue] Allow multiple values per key. |
| 9605 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 9606 * @returns {Object} Returns the new inverted object. |
| 9607 * @example |
| 9608 * |
| 9609 * var object = { 'a': 1, 'b': 2, 'c': 1 }; |
| 9610 * |
| 9611 * _.invert(object); |
| 9612 * // => { '1': 'c', '2': 'b' } |
| 9613 * |
| 9614 * // with `multiValue` |
| 9615 * _.invert(object, true); |
| 9616 * // => { '1': ['a', 'c'], '2': ['b'] } |
| 9617 */ |
| 9618 function invert(object, multiValue, guard) { |
| 9619 if (guard && isIterateeCall(object, multiValue, guard)) { |
| 9620 multiValue = undefined; |
| 9621 } |
| 9622 var index = -1, |
| 9623 props = keys(object), |
| 9624 length = props.length, |
| 9625 result = {}; |
| 9626 |
| 9627 while (++index < length) { |
| 9628 var key = props[index], |
| 9629 value = object[key]; |
| 9630 |
| 9631 if (multiValue) { |
| 9632 if (hasOwnProperty.call(result, value)) { |
| 9633 result[value].push(key); |
| 9634 } else { |
| 9635 result[value] = [key]; |
| 9636 } |
| 9637 } |
| 9638 else { |
| 9639 result[value] = key; |
| 9640 } |
| 9641 } |
| 9642 return result; |
| 9643 } |
| 9644 |
| 9645 /** |
| 9646 * Creates an array of the own enumerable property names of `object`. |
| 9647 * |
| 9648 * **Note:** Non-object values are coerced to objects. See the |
| 9649 * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) |
| 9650 * for more details. |
| 9651 * |
| 9652 * @static |
| 9653 * @memberOf _ |
| 9654 * @category Object |
| 9655 * @param {Object} object The object to query. |
| 9656 * @returns {Array} Returns the array of property names. |
| 9657 * @example |
| 9658 * |
| 9659 * function Foo() { |
| 9660 * this.a = 1; |
| 9661 * this.b = 2; |
| 9662 * } |
| 9663 * |
| 9664 * Foo.prototype.c = 3; |
| 9665 * |
| 9666 * _.keys(new Foo); |
| 9667 * // => ['a', 'b'] (iteration order is not guaranteed) |
| 9668 * |
| 9669 * _.keys('hi'); |
| 9670 * // => ['0', '1'] |
| 9671 */ |
| 9672 var keys = !nativeKeys ? shimKeys : function(object) { |
| 9673 var Ctor = object == null ? undefined : object.constructor; |
| 9674 if ((typeof Ctor == 'function' && Ctor.prototype === object) || |
| 9675 (typeof object != 'function' && isArrayLike(object))) { |
| 9676 return shimKeys(object); |
| 9677 } |
| 9678 return isObject(object) ? nativeKeys(object) : []; |
| 9679 }; |
| 9680 |
| 9681 /** |
| 9682 * Creates an array of the own and inherited enumerable property names of `o
bject`. |
| 9683 * |
| 9684 * **Note:** Non-object values are coerced to objects. |
| 9685 * |
| 9686 * @static |
| 9687 * @memberOf _ |
| 9688 * @category Object |
| 9689 * @param {Object} object The object to query. |
| 9690 * @returns {Array} Returns the array of property names. |
| 9691 * @example |
| 9692 * |
| 9693 * function Foo() { |
| 9694 * this.a = 1; |
| 9695 * this.b = 2; |
| 9696 * } |
| 9697 * |
| 9698 * Foo.prototype.c = 3; |
| 9699 * |
| 9700 * _.keysIn(new Foo); |
| 9701 * // => ['a', 'b', 'c'] (iteration order is not guaranteed) |
| 9702 */ |
| 9703 function keysIn(object) { |
| 9704 if (object == null) { |
| 9705 return []; |
| 9706 } |
| 9707 if (!isObject(object)) { |
| 9708 object = Object(object); |
| 9709 } |
| 9710 var length = object.length; |
| 9711 length = (length && isLength(length) && |
| 9712 (isArray(object) || isArguments(object)) && length) || 0; |
| 9713 |
| 9714 var Ctor = object.constructor, |
| 9715 index = -1, |
| 9716 isProto = typeof Ctor == 'function' && Ctor.prototype === object, |
| 9717 result = Array(length), |
| 9718 skipIndexes = length > 0; |
| 9719 |
| 9720 while (++index < length) { |
| 9721 result[index] = (index + ''); |
| 9722 } |
| 9723 for (var key in object) { |
| 9724 if (!(skipIndexes && isIndex(key, length)) && |
| 9725 !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, k
ey)))) { |
| 9726 result.push(key); |
| 9727 } |
| 9728 } |
| 9729 return result; |
| 9730 } |
| 9731 |
| 9732 /** |
| 9733 * The opposite of `_.mapValues`; this method creates an object with the |
| 9734 * same values as `object` and keys generated by running each own enumerable |
| 9735 * property of `object` through `iteratee`. |
| 9736 * |
| 9737 * @static |
| 9738 * @memberOf _ |
| 9739 * @category Object |
| 9740 * @param {Object} object The object to iterate over. |
| 9741 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 9742 * per iteration. |
| 9743 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 9744 * @returns {Object} Returns the new mapped object. |
| 9745 * @example |
| 9746 * |
| 9747 * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { |
| 9748 * return key + value; |
| 9749 * }); |
| 9750 * // => { 'a1': 1, 'b2': 2 } |
| 9751 */ |
| 9752 var mapKeys = createObjectMapper(true); |
| 9753 |
| 9754 /** |
| 9755 * Creates an object with the same keys as `object` and values generated by |
| 9756 * running each own enumerable property of `object` through `iteratee`. The |
| 9757 * iteratee function is bound to `thisArg` and invoked with three arguments: |
| 9758 * (value, key, object). |
| 9759 * |
| 9760 * If a property name is provided for `iteratee` the created `_.property` |
| 9761 * style callback returns the property value of the given element. |
| 9762 * |
| 9763 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 9764 * style callback returns `true` for elements that have a matching property |
| 9765 * value, else `false`. |
| 9766 * |
| 9767 * If an object is provided for `iteratee` the created `_.matches` style |
| 9768 * callback returns `true` for elements that have the properties of the give
n |
| 9769 * object, else `false`. |
| 9770 * |
| 9771 * @static |
| 9772 * @memberOf _ |
| 9773 * @category Object |
| 9774 * @param {Object} object The object to iterate over. |
| 9775 * @param {Function|Object|string} [iteratee=_.identity] The function invoke
d |
| 9776 * per iteration. |
| 9777 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 9778 * @returns {Object} Returns the new mapped object. |
| 9779 * @example |
| 9780 * |
| 9781 * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { |
| 9782 * return n * 3; |
| 9783 * }); |
| 9784 * // => { 'a': 3, 'b': 6 } |
| 9785 * |
| 9786 * var users = { |
| 9787 * 'fred': { 'user': 'fred', 'age': 40 }, |
| 9788 * 'pebbles': { 'user': 'pebbles', 'age': 1 } |
| 9789 * }; |
| 9790 * |
| 9791 * // using the `_.property` callback shorthand |
| 9792 * _.mapValues(users, 'age'); |
| 9793 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) |
| 9794 */ |
| 9795 var mapValues = createObjectMapper(); |
| 9796 |
| 9797 /** |
| 9798 * The opposite of `_.pick`; this method creates an object composed of the |
| 9799 * own and inherited enumerable properties of `object` that are not omitted. |
| 9800 * |
| 9801 * @static |
| 9802 * @memberOf _ |
| 9803 * @category Object |
| 9804 * @param {Object} object The source object. |
| 9805 * @param {Function|...(string|string[])} [predicate] The function invoked p
er |
| 9806 * iteration or property names to omit, specified as individual property |
| 9807 * names or arrays of property names. |
| 9808 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 9809 * @returns {Object} Returns the new object. |
| 9810 * @example |
| 9811 * |
| 9812 * var object = { 'user': 'fred', 'age': 40 }; |
| 9813 * |
| 9814 * _.omit(object, 'age'); |
| 9815 * // => { 'user': 'fred' } |
| 9816 * |
| 9817 * _.omit(object, _.isNumber); |
| 9818 * // => { 'user': 'fred' } |
| 9819 */ |
| 9820 var omit = restParam(function(object, props) { |
| 9821 if (object == null) { |
| 9822 return {}; |
| 9823 } |
| 9824 if (typeof props[0] != 'function') { |
| 9825 var props = arrayMap(baseFlatten(props), String); |
| 9826 return pickByArray(object, baseDifference(keysIn(object), props)); |
| 9827 } |
| 9828 var predicate = bindCallback(props[0], props[1], 3); |
| 9829 return pickByCallback(object, function(value, key, object) { |
| 9830 return !predicate(value, key, object); |
| 9831 }); |
| 9832 }); |
| 9833 |
| 9834 /** |
| 9835 * Creates a two dimensional array of the key-value pairs for `object`, |
| 9836 * e.g. `[[key1, value1], [key2, value2]]`. |
| 9837 * |
| 9838 * @static |
| 9839 * @memberOf _ |
| 9840 * @category Object |
| 9841 * @param {Object} object The object to query. |
| 9842 * @returns {Array} Returns the new array of key-value pairs. |
| 9843 * @example |
| 9844 * |
| 9845 * _.pairs({ 'barney': 36, 'fred': 40 }); |
| 9846 * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) |
| 9847 */ |
| 9848 function pairs(object) { |
| 9849 object = toObject(object); |
| 9850 |
| 9851 var index = -1, |
| 9852 props = keys(object), |
| 9853 length = props.length, |
| 9854 result = Array(length); |
| 9855 |
| 9856 while (++index < length) { |
| 9857 var key = props[index]; |
| 9858 result[index] = [key, object[key]]; |
| 9859 } |
| 9860 return result; |
| 9861 } |
| 9862 |
| 9863 /** |
| 9864 * Creates an object composed of the picked `object` properties. Property |
| 9865 * names may be specified as individual arguments or as arrays of property |
| 9866 * names. If `predicate` is provided it's invoked for each property of `obje
ct` |
| 9867 * picking the properties `predicate` returns truthy for. The predicate is |
| 9868 * bound to `thisArg` and invoked with three arguments: (value, key, object)
. |
| 9869 * |
| 9870 * @static |
| 9871 * @memberOf _ |
| 9872 * @category Object |
| 9873 * @param {Object} object The source object. |
| 9874 * @param {Function|...(string|string[])} [predicate] The function invoked p
er |
| 9875 * iteration or property names to pick, specified as individual property |
| 9876 * names or arrays of property names. |
| 9877 * @param {*} [thisArg] The `this` binding of `predicate`. |
| 9878 * @returns {Object} Returns the new object. |
| 9879 * @example |
| 9880 * |
| 9881 * var object = { 'user': 'fred', 'age': 40 }; |
| 9882 * |
| 9883 * _.pick(object, 'user'); |
| 9884 * // => { 'user': 'fred' } |
| 9885 * |
| 9886 * _.pick(object, _.isString); |
| 9887 * // => { 'user': 'fred' } |
| 9888 */ |
| 9889 var pick = restParam(function(object, props) { |
| 9890 if (object == null) { |
| 9891 return {}; |
| 9892 } |
| 9893 return typeof props[0] == 'function' |
| 9894 ? pickByCallback(object, bindCallback(props[0], props[1], 3)) |
| 9895 : pickByArray(object, baseFlatten(props)); |
| 9896 }); |
| 9897 |
| 9898 /** |
| 9899 * This method is like `_.get` except that if the resolved value is a functi
on |
| 9900 * it's invoked with the `this` binding of its parent object and its result |
| 9901 * is returned. |
| 9902 * |
| 9903 * @static |
| 9904 * @memberOf _ |
| 9905 * @category Object |
| 9906 * @param {Object} object The object to query. |
| 9907 * @param {Array|string} path The path of the property to resolve. |
| 9908 * @param {*} [defaultValue] The value returned if the resolved value is `un
defined`. |
| 9909 * @returns {*} Returns the resolved value. |
| 9910 * @example |
| 9911 * |
| 9912 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; |
| 9913 * |
| 9914 * _.result(object, 'a[0].b.c1'); |
| 9915 * // => 3 |
| 9916 * |
| 9917 * _.result(object, 'a[0].b.c2'); |
| 9918 * // => 4 |
| 9919 * |
| 9920 * _.result(object, 'a.b.c', 'default'); |
| 9921 * // => 'default' |
| 9922 * |
| 9923 * _.result(object, 'a.b.c', _.constant('default')); |
| 9924 * // => 'default' |
| 9925 */ |
| 9926 function result(object, path, defaultValue) { |
| 9927 var result = object == null ? undefined : object[path]; |
| 9928 if (result === undefined) { |
| 9929 if (object != null && !isKey(path, object)) { |
| 9930 path = toPath(path); |
| 9931 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0
, -1)); |
| 9932 result = object == null ? undefined : object[last(path)]; |
| 9933 } |
| 9934 result = result === undefined ? defaultValue : result; |
| 9935 } |
| 9936 return isFunction(result) ? result.call(object) : result; |
| 9937 } |
| 9938 |
| 9939 /** |
| 9940 * Sets the property value of `path` on `object`. If a portion of `path` |
| 9941 * does not exist it's created. |
| 9942 * |
| 9943 * @static |
| 9944 * @memberOf _ |
| 9945 * @category Object |
| 9946 * @param {Object} object The object to augment. |
| 9947 * @param {Array|string} path The path of the property to set. |
| 9948 * @param {*} value The value to set. |
| 9949 * @returns {Object} Returns `object`. |
| 9950 * @example |
| 9951 * |
| 9952 * var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
| 9953 * |
| 9954 * _.set(object, 'a[0].b.c', 4); |
| 9955 * console.log(object.a[0].b.c); |
| 9956 * // => 4 |
| 9957 * |
| 9958 * _.set(object, 'x[0].y.z', 5); |
| 9959 * console.log(object.x[0].y.z); |
| 9960 * // => 5 |
| 9961 */ |
| 9962 function set(object, path, value) { |
| 9963 if (object == null) { |
| 9964 return object; |
| 9965 } |
| 9966 var pathKey = (path + ''); |
| 9967 path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPa
th(path); |
| 9968 |
| 9969 var index = -1, |
| 9970 length = path.length, |
| 9971 lastIndex = length - 1, |
| 9972 nested = object; |
| 9973 |
| 9974 while (nested != null && ++index < length) { |
| 9975 var key = path[index]; |
| 9976 if (isObject(nested)) { |
| 9977 if (index == lastIndex) { |
| 9978 nested[key] = value; |
| 9979 } else if (nested[key] == null) { |
| 9980 nested[key] = isIndex(path[index + 1]) ? [] : {}; |
| 9981 } |
| 9982 } |
| 9983 nested = nested[key]; |
| 9984 } |
| 9985 return object; |
| 9986 } |
| 9987 |
| 9988 /** |
| 9989 * An alternative to `_.reduce`; this method transforms `object` to a new |
| 9990 * `accumulator` object which is the result of running each of its own enume
rable |
| 9991 * properties through `iteratee`, with each invocation potentially mutating |
| 9992 * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoke
d |
| 9993 * with four arguments: (accumulator, value, key, object). Iteratee function
s |
| 9994 * may exit iteration early by explicitly returning `false`. |
| 9995 * |
| 9996 * @static |
| 9997 * @memberOf _ |
| 9998 * @category Object |
| 9999 * @param {Array|Object} object The object to iterate over. |
| 10000 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 10001 * @param {*} [accumulator] The custom accumulator value. |
| 10002 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 10003 * @returns {*} Returns the accumulated value. |
| 10004 * @example |
| 10005 * |
| 10006 * _.transform([2, 3, 4], function(result, n) { |
| 10007 * result.push(n *= n); |
| 10008 * return n % 2 == 0; |
| 10009 * }); |
| 10010 * // => [4, 9] |
| 10011 * |
| 10012 * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { |
| 10013 * result[key] = n * 3; |
| 10014 * }); |
| 10015 * // => { 'a': 3, 'b': 6 } |
| 10016 */ |
| 10017 function transform(object, iteratee, accumulator, thisArg) { |
| 10018 var isArr = isArray(object) || isTypedArray(object); |
| 10019 iteratee = getCallback(iteratee, thisArg, 4); |
| 10020 |
| 10021 if (accumulator == null) { |
| 10022 if (isArr || isObject(object)) { |
| 10023 var Ctor = object.constructor; |
| 10024 if (isArr) { |
| 10025 accumulator = isArray(object) ? new Ctor : []; |
| 10026 } else { |
| 10027 accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefin
ed); |
| 10028 } |
| 10029 } else { |
| 10030 accumulator = {}; |
| 10031 } |
| 10032 } |
| 10033 (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { |
| 10034 return iteratee(accumulator, value, index, object); |
| 10035 }); |
| 10036 return accumulator; |
| 10037 } |
| 10038 |
| 10039 /** |
| 10040 * Creates an array of the own enumerable property values of `object`. |
| 10041 * |
| 10042 * **Note:** Non-object values are coerced to objects. |
| 10043 * |
| 10044 * @static |
| 10045 * @memberOf _ |
| 10046 * @category Object |
| 10047 * @param {Object} object The object to query. |
| 10048 * @returns {Array} Returns the array of property values. |
| 10049 * @example |
| 10050 * |
| 10051 * function Foo() { |
| 10052 * this.a = 1; |
| 10053 * this.b = 2; |
| 10054 * } |
| 10055 * |
| 10056 * Foo.prototype.c = 3; |
| 10057 * |
| 10058 * _.values(new Foo); |
| 10059 * // => [1, 2] (iteration order is not guaranteed) |
| 10060 * |
| 10061 * _.values('hi'); |
| 10062 * // => ['h', 'i'] |
| 10063 */ |
| 10064 function values(object) { |
| 10065 return baseValues(object, keys(object)); |
| 10066 } |
| 10067 |
| 10068 /** |
| 10069 * Creates an array of the own and inherited enumerable property values |
| 10070 * of `object`. |
| 10071 * |
| 10072 * **Note:** Non-object values are coerced to objects. |
| 10073 * |
| 10074 * @static |
| 10075 * @memberOf _ |
| 10076 * @category Object |
| 10077 * @param {Object} object The object to query. |
| 10078 * @returns {Array} Returns the array of property values. |
| 10079 * @example |
| 10080 * |
| 10081 * function Foo() { |
| 10082 * this.a = 1; |
| 10083 * this.b = 2; |
| 10084 * } |
| 10085 * |
| 10086 * Foo.prototype.c = 3; |
| 10087 * |
| 10088 * _.valuesIn(new Foo); |
| 10089 * // => [1, 2, 3] (iteration order is not guaranteed) |
| 10090 */ |
| 10091 function valuesIn(object) { |
| 10092 return baseValues(object, keysIn(object)); |
| 10093 } |
| 10094 |
| 10095 /*------------------------------------------------------------------------*/ |
| 10096 |
| 10097 /** |
| 10098 * Checks if `n` is between `start` and up to but not including, `end`. If |
| 10099 * `end` is not specified it's set to `start` with `start` then set to `0`. |
| 10100 * |
| 10101 * @static |
| 10102 * @memberOf _ |
| 10103 * @category Number |
| 10104 * @param {number} n The number to check. |
| 10105 * @param {number} [start=0] The start of the range. |
| 10106 * @param {number} end The end of the range. |
| 10107 * @returns {boolean} Returns `true` if `n` is in the range, else `false`. |
| 10108 * @example |
| 10109 * |
| 10110 * _.inRange(3, 2, 4); |
| 10111 * // => true |
| 10112 * |
| 10113 * _.inRange(4, 8); |
| 10114 * // => true |
| 10115 * |
| 10116 * _.inRange(4, 2); |
| 10117 * // => false |
| 10118 * |
| 10119 * _.inRange(2, 2); |
| 10120 * // => false |
| 10121 * |
| 10122 * _.inRange(1.2, 2); |
| 10123 * // => true |
| 10124 * |
| 10125 * _.inRange(5.2, 4); |
| 10126 * // => false |
| 10127 */ |
| 10128 function inRange(value, start, end) { |
| 10129 start = +start || 0; |
| 10130 if (end === undefined) { |
| 10131 end = start; |
| 10132 start = 0; |
| 10133 } else { |
| 10134 end = +end || 0; |
| 10135 } |
| 10136 return value >= nativeMin(start, end) && value < nativeMax(start, end); |
| 10137 } |
| 10138 |
| 10139 /** |
| 10140 * Produces a random number between `min` and `max` (inclusive). If only one |
| 10141 * argument is provided a number between `0` and the given number is returne
d. |
| 10142 * If `floating` is `true`, or either `min` or `max` are floats, a floating-
point |
| 10143 * number is returned instead of an integer. |
| 10144 * |
| 10145 * @static |
| 10146 * @memberOf _ |
| 10147 * @category Number |
| 10148 * @param {number} [min=0] The minimum possible value. |
| 10149 * @param {number} [max=1] The maximum possible value. |
| 10150 * @param {boolean} [floating] Specify returning a floating-point number. |
| 10151 * @returns {number} Returns the random number. |
| 10152 * @example |
| 10153 * |
| 10154 * _.random(0, 5); |
| 10155 * // => an integer between 0 and 5 |
| 10156 * |
| 10157 * _.random(5); |
| 10158 * // => also an integer between 0 and 5 |
| 10159 * |
| 10160 * _.random(5, true); |
| 10161 * // => a floating-point number between 0 and 5 |
| 10162 * |
| 10163 * _.random(1.2, 5.2); |
| 10164 * // => a floating-point number between 1.2 and 5.2 |
| 10165 */ |
| 10166 function random(min, max, floating) { |
| 10167 if (floating && isIterateeCall(min, max, floating)) { |
| 10168 max = floating = undefined; |
| 10169 } |
| 10170 var noMin = min == null, |
| 10171 noMax = max == null; |
| 10172 |
| 10173 if (floating == null) { |
| 10174 if (noMax && typeof min == 'boolean') { |
| 10175 floating = min; |
| 10176 min = 1; |
| 10177 } |
| 10178 else if (typeof max == 'boolean') { |
| 10179 floating = max; |
| 10180 noMax = true; |
| 10181 } |
| 10182 } |
| 10183 if (noMin && noMax) { |
| 10184 max = 1; |
| 10185 noMax = false; |
| 10186 } |
| 10187 min = +min || 0; |
| 10188 if (noMax) { |
| 10189 max = min; |
| 10190 min = 0; |
| 10191 } else { |
| 10192 max = +max || 0; |
| 10193 } |
| 10194 if (floating || min % 1 || max % 1) { |
| 10195 var rand = nativeRandom(); |
| 10196 return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +
'').length - 1)))), max); |
| 10197 } |
| 10198 return baseRandom(min, max); |
| 10199 } |
| 10200 |
| 10201 /*------------------------------------------------------------------------*/ |
| 10202 |
| 10203 /** |
| 10204 * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase
). |
| 10205 * |
| 10206 * @static |
| 10207 * @memberOf _ |
| 10208 * @category String |
| 10209 * @param {string} [string=''] The string to convert. |
| 10210 * @returns {string} Returns the camel cased string. |
| 10211 * @example |
| 10212 * |
| 10213 * _.camelCase('Foo Bar'); |
| 10214 * // => 'fooBar' |
| 10215 * |
| 10216 * _.camelCase('--foo-bar'); |
| 10217 * // => 'fooBar' |
| 10218 * |
| 10219 * _.camelCase('__foo_bar__'); |
| 10220 * // => 'fooBar' |
| 10221 */ |
| 10222 var camelCase = createCompounder(function(result, word, index) { |
| 10223 word = word.toLowerCase(); |
| 10224 return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) :
word); |
| 10225 }); |
| 10226 |
| 10227 /** |
| 10228 * Capitalizes the first character of `string`. |
| 10229 * |
| 10230 * @static |
| 10231 * @memberOf _ |
| 10232 * @category String |
| 10233 * @param {string} [string=''] The string to capitalize. |
| 10234 * @returns {string} Returns the capitalized string. |
| 10235 * @example |
| 10236 * |
| 10237 * _.capitalize('fred'); |
| 10238 * // => 'Fred' |
| 10239 */ |
| 10240 function capitalize(string) { |
| 10241 string = baseToString(string); |
| 10242 return string && (string.charAt(0).toUpperCase() + string.slice(1)); |
| 10243 } |
| 10244 |
| 10245 /** |
| 10246 * Deburrs `string` by converting [latin-1 supplementary letters](https://en
.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) |
| 10247 * to basic latin letters and removing [combining diacritical marks](https:/
/en.wikipedia.org/wiki/Combining_Diacritical_Marks). |
| 10248 * |
| 10249 * @static |
| 10250 * @memberOf _ |
| 10251 * @category String |
| 10252 * @param {string} [string=''] The string to deburr. |
| 10253 * @returns {string} Returns the deburred string. |
| 10254 * @example |
| 10255 * |
| 10256 * _.deburr('déjà vu'); |
| 10257 * // => 'deja vu' |
| 10258 */ |
| 10259 function deburr(string) { |
| 10260 string = baseToString(string); |
| 10261 return string && string.replace(reLatin1, deburrLetter).replace(reComboMar
k, ''); |
| 10262 } |
| 10263 |
| 10264 /** |
| 10265 * Checks if `string` ends with the given target string. |
| 10266 * |
| 10267 * @static |
| 10268 * @memberOf _ |
| 10269 * @category String |
| 10270 * @param {string} [string=''] The string to search. |
| 10271 * @param {string} [target] The string to search for. |
| 10272 * @param {number} [position=string.length] The position to search from. |
| 10273 * @returns {boolean} Returns `true` if `string` ends with `target`, else `f
alse`. |
| 10274 * @example |
| 10275 * |
| 10276 * _.endsWith('abc', 'c'); |
| 10277 * // => true |
| 10278 * |
| 10279 * _.endsWith('abc', 'b'); |
| 10280 * // => false |
| 10281 * |
| 10282 * _.endsWith('abc', 'b', 2); |
| 10283 * // => true |
| 10284 */ |
| 10285 function endsWith(string, target, position) { |
| 10286 string = baseToString(string); |
| 10287 target = (target + ''); |
| 10288 |
| 10289 var length = string.length; |
| 10290 position = position === undefined |
| 10291 ? length |
| 10292 : nativeMin(position < 0 ? 0 : (+position || 0), length); |
| 10293 |
| 10294 position -= target.length; |
| 10295 return position >= 0 && string.indexOf(target, position) == position; |
| 10296 } |
| 10297 |
| 10298 /** |
| 10299 * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to |
| 10300 * their corresponding HTML entities. |
| 10301 * |
| 10302 * **Note:** No other characters are escaped. To escape additional character
s |
| 10303 * use a third-party library like [_he_](https://mths.be/he). |
| 10304 * |
| 10305 * Though the ">" character is escaped for symmetry, characters like |
| 10306 * ">" and "/" don't need escaping in HTML and have no special meaning |
| 10307 * unless they're part of a tag or unquoted attribute value. |
| 10308 * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-a
mpersands) |
| 10309 * (under "semi-related fun fact") for more details. |
| 10310 * |
| 10311 * Backticks are escaped because in Internet Explorer < 9, they can break ou
t |
| 10312 * of attribute values or HTML comments. See [#59](https://html5sec.org/#59)
, |
| 10313 * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and |
| 10314 * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](http
s://html5sec.org/) |
| 10315 * for more details. |
| 10316 * |
| 10317 * When working with HTML you should always [quote attribute values](http://
wonko.com/post/html-escaping) |
| 10318 * to reduce XSS vectors. |
| 10319 * |
| 10320 * @static |
| 10321 * @memberOf _ |
| 10322 * @category String |
| 10323 * @param {string} [string=''] The string to escape. |
| 10324 * @returns {string} Returns the escaped string. |
| 10325 * @example |
| 10326 * |
| 10327 * _.escape('fred, barney, & pebbles'); |
| 10328 * // => 'fred, barney, & pebbles' |
| 10329 */ |
| 10330 function escape(string) { |
| 10331 // Reset `lastIndex` because in IE < 9 `String#replace` does not. |
| 10332 string = baseToString(string); |
| 10333 return (string && reHasUnescapedHtml.test(string)) |
| 10334 ? string.replace(reUnescapedHtml, escapeHtmlChar) |
| 10335 : string; |
| 10336 } |
| 10337 |
| 10338 /** |
| 10339 * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?"
, |
| 10340 * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. |
| 10341 * |
| 10342 * @static |
| 10343 * @memberOf _ |
| 10344 * @category String |
| 10345 * @param {string} [string=''] The string to escape. |
| 10346 * @returns {string} Returns the escaped string. |
| 10347 * @example |
| 10348 * |
| 10349 * _.escapeRegExp('[lodash](https://lodash.com/)'); |
| 10350 * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' |
| 10351 */ |
| 10352 function escapeRegExp(string) { |
| 10353 string = baseToString(string); |
| 10354 return (string && reHasRegExpChars.test(string)) |
| 10355 ? string.replace(reRegExpChars, escapeRegExpChar) |
| 10356 : (string || '(?:)'); |
| 10357 } |
| 10358 |
| 10359 /** |
| 10360 * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_ca
se#Special_case_styles). |
| 10361 * |
| 10362 * @static |
| 10363 * @memberOf _ |
| 10364 * @category String |
| 10365 * @param {string} [string=''] The string to convert. |
| 10366 * @returns {string} Returns the kebab cased string. |
| 10367 * @example |
| 10368 * |
| 10369 * _.kebabCase('Foo Bar'); |
| 10370 * // => 'foo-bar' |
| 10371 * |
| 10372 * _.kebabCase('fooBar'); |
| 10373 * // => 'foo-bar' |
| 10374 * |
| 10375 * _.kebabCase('__foo_bar__'); |
| 10376 * // => 'foo-bar' |
| 10377 */ |
| 10378 var kebabCase = createCompounder(function(result, word, index) { |
| 10379 return result + (index ? '-' : '') + word.toLowerCase(); |
| 10380 }); |
| 10381 |
| 10382 /** |
| 10383 * Pads `string` on the left and right sides if it's shorter than `length`. |
| 10384 * Padding characters are truncated if they can't be evenly divided by `leng
th`. |
| 10385 * |
| 10386 * @static |
| 10387 * @memberOf _ |
| 10388 * @category String |
| 10389 * @param {string} [string=''] The string to pad. |
| 10390 * @param {number} [length=0] The padding length. |
| 10391 * @param {string} [chars=' '] The string used as padding. |
| 10392 * @returns {string} Returns the padded string. |
| 10393 * @example |
| 10394 * |
| 10395 * _.pad('abc', 8); |
| 10396 * // => ' abc ' |
| 10397 * |
| 10398 * _.pad('abc', 8, '_-'); |
| 10399 * // => '_-abc_-_' |
| 10400 * |
| 10401 * _.pad('abc', 3); |
| 10402 * // => 'abc' |
| 10403 */ |
| 10404 function pad(string, length, chars) { |
| 10405 string = baseToString(string); |
| 10406 length = +length; |
| 10407 |
| 10408 var strLength = string.length; |
| 10409 if (strLength >= length || !nativeIsFinite(length)) { |
| 10410 return string; |
| 10411 } |
| 10412 var mid = (length - strLength) / 2, |
| 10413 leftLength = nativeFloor(mid), |
| 10414 rightLength = nativeCeil(mid); |
| 10415 |
| 10416 chars = createPadding('', rightLength, chars); |
| 10417 return chars.slice(0, leftLength) + string + chars; |
| 10418 } |
| 10419 |
| 10420 /** |
| 10421 * Pads `string` on the left side if it's shorter than `length`. Padding |
| 10422 * characters are truncated if they exceed `length`. |
| 10423 * |
| 10424 * @static |
| 10425 * @memberOf _ |
| 10426 * @category String |
| 10427 * @param {string} [string=''] The string to pad. |
| 10428 * @param {number} [length=0] The padding length. |
| 10429 * @param {string} [chars=' '] The string used as padding. |
| 10430 * @returns {string} Returns the padded string. |
| 10431 * @example |
| 10432 * |
| 10433 * _.padLeft('abc', 6); |
| 10434 * // => ' abc' |
| 10435 * |
| 10436 * _.padLeft('abc', 6, '_-'); |
| 10437 * // => '_-_abc' |
| 10438 * |
| 10439 * _.padLeft('abc', 3); |
| 10440 * // => 'abc' |
| 10441 */ |
| 10442 var padLeft = createPadDir(); |
| 10443 |
| 10444 /** |
| 10445 * Pads `string` on the right side if it's shorter than `length`. Padding |
| 10446 * characters are truncated if they exceed `length`. |
| 10447 * |
| 10448 * @static |
| 10449 * @memberOf _ |
| 10450 * @category String |
| 10451 * @param {string} [string=''] The string to pad. |
| 10452 * @param {number} [length=0] The padding length. |
| 10453 * @param {string} [chars=' '] The string used as padding. |
| 10454 * @returns {string} Returns the padded string. |
| 10455 * @example |
| 10456 * |
| 10457 * _.padRight('abc', 6); |
| 10458 * // => 'abc ' |
| 10459 * |
| 10460 * _.padRight('abc', 6, '_-'); |
| 10461 * // => 'abc_-_' |
| 10462 * |
| 10463 * _.padRight('abc', 3); |
| 10464 * // => 'abc' |
| 10465 */ |
| 10466 var padRight = createPadDir(true); |
| 10467 |
| 10468 /** |
| 10469 * Converts `string` to an integer of the specified radix. If `radix` is |
| 10470 * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadec
imal, |
| 10471 * in which case a `radix` of `16` is used. |
| 10472 * |
| 10473 * **Note:** This method aligns with the [ES5 implementation](https://es5.gi
thub.io/#E) |
| 10474 * of `parseInt`. |
| 10475 * |
| 10476 * @static |
| 10477 * @memberOf _ |
| 10478 * @category String |
| 10479 * @param {string} string The string to convert. |
| 10480 * @param {number} [radix] The radix to interpret `value` by. |
| 10481 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 10482 * @returns {number} Returns the converted integer. |
| 10483 * @example |
| 10484 * |
| 10485 * _.parseInt('08'); |
| 10486 * // => 8 |
| 10487 * |
| 10488 * _.map(['6', '08', '10'], _.parseInt); |
| 10489 * // => [6, 8, 10] |
| 10490 */ |
| 10491 function parseInt(string, radix, guard) { |
| 10492 // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. |
| 10493 // Chrome fails to trim leading <BOM> whitespace characters. |
| 10494 // See https://code.google.com/p/v8/issues/detail?id=3109 for more details
. |
| 10495 if (guard ? isIterateeCall(string, radix, guard) : radix == null) { |
| 10496 radix = 0; |
| 10497 } else if (radix) { |
| 10498 radix = +radix; |
| 10499 } |
| 10500 string = trim(string); |
| 10501 return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 :
10)); |
| 10502 } |
| 10503 |
| 10504 /** |
| 10505 * Repeats the given string `n` times. |
| 10506 * |
| 10507 * @static |
| 10508 * @memberOf _ |
| 10509 * @category String |
| 10510 * @param {string} [string=''] The string to repeat. |
| 10511 * @param {number} [n=0] The number of times to repeat the string. |
| 10512 * @returns {string} Returns the repeated string. |
| 10513 * @example |
| 10514 * |
| 10515 * _.repeat('*', 3); |
| 10516 * // => '***' |
| 10517 * |
| 10518 * _.repeat('abc', 2); |
| 10519 * // => 'abcabc' |
| 10520 * |
| 10521 * _.repeat('abc', 0); |
| 10522 * // => '' |
| 10523 */ |
| 10524 function repeat(string, n) { |
| 10525 var result = ''; |
| 10526 string = baseToString(string); |
| 10527 n = +n; |
| 10528 if (n < 1 || !string || !nativeIsFinite(n)) { |
| 10529 return result; |
| 10530 } |
| 10531 // Leverage the exponentiation by squaring algorithm for a faster repeat. |
| 10532 // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more d
etails. |
| 10533 do { |
| 10534 if (n % 2) { |
| 10535 result += string; |
| 10536 } |
| 10537 n = nativeFloor(n / 2); |
| 10538 string += string; |
| 10539 } while (n); |
| 10540 |
| 10541 return result; |
| 10542 } |
| 10543 |
| 10544 /** |
| 10545 * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_cas
e). |
| 10546 * |
| 10547 * @static |
| 10548 * @memberOf _ |
| 10549 * @category String |
| 10550 * @param {string} [string=''] The string to convert. |
| 10551 * @returns {string} Returns the snake cased string. |
| 10552 * @example |
| 10553 * |
| 10554 * _.snakeCase('Foo Bar'); |
| 10555 * // => 'foo_bar' |
| 10556 * |
| 10557 * _.snakeCase('fooBar'); |
| 10558 * // => 'foo_bar' |
| 10559 * |
| 10560 * _.snakeCase('--foo-bar'); |
| 10561 * // => 'foo_bar' |
| 10562 */ |
| 10563 var snakeCase = createCompounder(function(result, word, index) { |
| 10564 return result + (index ? '_' : '') + word.toLowerCase(); |
| 10565 }); |
| 10566 |
| 10567 /** |
| 10568 * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_ca
se#Stylistic_or_specialised_usage). |
| 10569 * |
| 10570 * @static |
| 10571 * @memberOf _ |
| 10572 * @category String |
| 10573 * @param {string} [string=''] The string to convert. |
| 10574 * @returns {string} Returns the start cased string. |
| 10575 * @example |
| 10576 * |
| 10577 * _.startCase('--foo-bar'); |
| 10578 * // => 'Foo Bar' |
| 10579 * |
| 10580 * _.startCase('fooBar'); |
| 10581 * // => 'Foo Bar' |
| 10582 * |
| 10583 * _.startCase('__foo_bar__'); |
| 10584 * // => 'Foo Bar' |
| 10585 */ |
| 10586 var startCase = createCompounder(function(result, word, index) { |
| 10587 return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.
slice(1)); |
| 10588 }); |
| 10589 |
| 10590 /** |
| 10591 * Checks if `string` starts with the given target string. |
| 10592 * |
| 10593 * @static |
| 10594 * @memberOf _ |
| 10595 * @category String |
| 10596 * @param {string} [string=''] The string to search. |
| 10597 * @param {string} [target] The string to search for. |
| 10598 * @param {number} [position=0] The position to search from. |
| 10599 * @returns {boolean} Returns `true` if `string` starts with `target`, else
`false`. |
| 10600 * @example |
| 10601 * |
| 10602 * _.startsWith('abc', 'a'); |
| 10603 * // => true |
| 10604 * |
| 10605 * _.startsWith('abc', 'b'); |
| 10606 * // => false |
| 10607 * |
| 10608 * _.startsWith('abc', 'b', 1); |
| 10609 * // => true |
| 10610 */ |
| 10611 function startsWith(string, target, position) { |
| 10612 string = baseToString(string); |
| 10613 position = position == null |
| 10614 ? 0 |
| 10615 : nativeMin(position < 0 ? 0 : (+position || 0), string.length); |
| 10616 |
| 10617 return string.lastIndexOf(target, position) == position; |
| 10618 } |
| 10619 |
| 10620 /** |
| 10621 * Creates a compiled template function that can interpolate data properties |
| 10622 * in "interpolate" delimiters, HTML-escape interpolated data properties in |
| 10623 * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Dat
a |
| 10624 * properties may be accessed as free variables in the template. If a settin
g |
| 10625 * object is provided it takes precedence over `_.templateSettings` values. |
| 10626 * |
| 10627 * **Note:** In the development build `_.template` utilizes |
| 10628 * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/source
maps/#toc-sourceurl) |
| 10629 * for easier debugging. |
| 10630 * |
| 10631 * For more information on precompiling templates see |
| 10632 * [lodash's custom builds documentation](https://lodash.com/custom-builds). |
| 10633 * |
| 10634 * For more information on Chrome extension sandboxes see |
| 10635 * [Chrome's extensions documentation](https://developer.chrome.com/extensio
ns/sandboxingEval). |
| 10636 * |
| 10637 * @static |
| 10638 * @memberOf _ |
| 10639 * @category String |
| 10640 * @param {string} [string=''] The template string. |
| 10641 * @param {Object} [options] The options object. |
| 10642 * @param {RegExp} [options.escape] The HTML "escape" delimiter. |
| 10643 * @param {RegExp} [options.evaluate] The "evaluate" delimiter. |
| 10644 * @param {Object} [options.imports] An object to import into the template a
s free variables. |
| 10645 * @param {RegExp} [options.interpolate] The "interpolate" delimiter. |
| 10646 * @param {string} [options.sourceURL] The sourceURL of the template's compi
led source. |
| 10647 * @param {string} [options.variable] The data object variable name. |
| 10648 * @param- {Object} [otherOptions] Enables the legacy `options` param signat
ure. |
| 10649 * @returns {Function} Returns the compiled template function. |
| 10650 * @example |
| 10651 * |
| 10652 * // using the "interpolate" delimiter to create a compiled template |
| 10653 * var compiled = _.template('hello <%= user %>!'); |
| 10654 * compiled({ 'user': 'fred' }); |
| 10655 * // => 'hello fred!' |
| 10656 * |
| 10657 * // using the HTML "escape" delimiter to escape data property values |
| 10658 * var compiled = _.template('<b><%- value %></b>'); |
| 10659 * compiled({ 'value': '<script>' }); |
| 10660 * // => '<b><script></b>' |
| 10661 * |
| 10662 * // using the "evaluate" delimiter to execute JavaScript and generate HTML |
| 10663 * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%-
user %></li><% }); %>'); |
| 10664 * compiled({ 'users': ['fred', 'barney'] }); |
| 10665 * // => '<li>fred</li><li>barney</li>' |
| 10666 * |
| 10667 * // using the internal `print` function in "evaluate" delimiters |
| 10668 * var compiled = _.template('<% print("hello " + user); %>!'); |
| 10669 * compiled({ 'user': 'barney' }); |
| 10670 * // => 'hello barney!' |
| 10671 * |
| 10672 * // using the ES delimiter as an alternative to the default "interpolate"
delimiter |
| 10673 * var compiled = _.template('hello ${ user }!'); |
| 10674 * compiled({ 'user': 'pebbles' }); |
| 10675 * // => 'hello pebbles!' |
| 10676 * |
| 10677 * // using custom template delimiters |
| 10678 * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; |
| 10679 * var compiled = _.template('hello {{ user }}!'); |
| 10680 * compiled({ 'user': 'mustache' }); |
| 10681 * // => 'hello mustache!' |
| 10682 * |
| 10683 * // using backslashes to treat delimiters as plain text |
| 10684 * var compiled = _.template('<%= "\\<%- value %\\>" %>'); |
| 10685 * compiled({ 'value': 'ignored' }); |
| 10686 * // => '<%- value %>' |
| 10687 * |
| 10688 * // using the `imports` option to import `jQuery` as `jq` |
| 10689 * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }
); %>'; |
| 10690 * var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); |
| 10691 * compiled({ 'users': ['fred', 'barney'] }); |
| 10692 * // => '<li>fred</li><li>barney</li>' |
| 10693 * |
| 10694 * // using the `sourceURL` option to specify a custom sourceURL for the tem
plate |
| 10695 * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/gr
eeting.jst' }); |
| 10696 * compiled(data); |
| 10697 * // => find the source of "greeting.jst" under the Sources tab or Resource
s panel of the web inspector |
| 10698 * |
| 10699 * // using the `variable` option to ensure a with-statement isn't used in t
he compiled template |
| 10700 * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' })
; |
| 10701 * compiled.source; |
| 10702 * // => function(data) { |
| 10703 * // var __t, __p = ''; |
| 10704 * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; |
| 10705 * // return __p; |
| 10706 * // } |
| 10707 * |
| 10708 * // using the `source` property to inline compiled templates for meaningfu
l |
| 10709 * // line numbers in error messages and a stack trace |
| 10710 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ |
| 10711 * var JST = {\ |
| 10712 * "main": ' + _.template(mainText).source + '\ |
| 10713 * };\ |
| 10714 * '); |
| 10715 */ |
| 10716 function template(string, options, otherOptions) { |
| 10717 // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/java
script-micro-templating/) |
| 10718 // and Laura Doktorova's doT.js (https://github.com/olado/doT). |
| 10719 var settings = lodash.templateSettings; |
| 10720 |
| 10721 if (otherOptions && isIterateeCall(string, options, otherOptions)) { |
| 10722 options = otherOptions = undefined; |
| 10723 } |
| 10724 string = baseToString(string); |
| 10725 options = assignWith(baseAssign({}, otherOptions || options), settings, as
signOwnDefaults); |
| 10726 |
| 10727 var imports = assignWith(baseAssign({}, options.imports), settings.imports
, assignOwnDefaults), |
| 10728 importsKeys = keys(imports), |
| 10729 importsValues = baseValues(imports, importsKeys); |
| 10730 |
| 10731 var isEscaping, |
| 10732 isEvaluating, |
| 10733 index = 0, |
| 10734 interpolate = options.interpolate || reNoMatch, |
| 10735 source = "__p += '"; |
| 10736 |
| 10737 // Compile the regexp to match each delimiter. |
| 10738 var reDelimiters = RegExp( |
| 10739 (options.escape || reNoMatch).source + '|' + |
| 10740 interpolate.source + '|' + |
| 10741 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|'
+ |
| 10742 (options.evaluate || reNoMatch).source + '|$' |
| 10743 , 'g'); |
| 10744 |
| 10745 // Use a sourceURL for easier debugging. |
| 10746 var sourceURL = '//# sourceURL=' + |
| 10747 ('sourceURL' in options |
| 10748 ? options.sourceURL |
| 10749 : ('lodash.templateSources[' + (++templateCounter) + ']') |
| 10750 ) + '\n'; |
| 10751 |
| 10752 string.replace(reDelimiters, function(match, escapeValue, interpolateValue
, esTemplateValue, evaluateValue, offset) { |
| 10753 interpolateValue || (interpolateValue = esTemplateValue); |
| 10754 |
| 10755 // Escape characters that can't be included in string literals. |
| 10756 source += string.slice(index, offset).replace(reUnescapedString, escapeS
tringChar); |
| 10757 |
| 10758 // Replace delimiters with snippets. |
| 10759 if (escapeValue) { |
| 10760 isEscaping = true; |
| 10761 source += "' +\n__e(" + escapeValue + ") +\n'"; |
| 10762 } |
| 10763 if (evaluateValue) { |
| 10764 isEvaluating = true; |
| 10765 source += "';\n" + evaluateValue + ";\n__p += '"; |
| 10766 } |
| 10767 if (interpolateValue) { |
| 10768 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t
) +\n'"; |
| 10769 } |
| 10770 index = offset + match.length; |
| 10771 |
| 10772 // The JS engine embedded in Adobe products requires returning the `matc
h` |
| 10773 // string in order to produce the correct `offset` value. |
| 10774 return match; |
| 10775 }); |
| 10776 |
| 10777 source += "';\n"; |
| 10778 |
| 10779 // If `variable` is not specified wrap a with-statement around the generat
ed |
| 10780 // code to add the data object to the top of the scope chain. |
| 10781 var variable = options.variable; |
| 10782 if (!variable) { |
| 10783 source = 'with (obj) {\n' + source + '\n}\n'; |
| 10784 } |
| 10785 // Cleanup code by stripping empty strings. |
| 10786 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source
) |
| 10787 .replace(reEmptyStringMiddle, '$1') |
| 10788 .replace(reEmptyStringTrailing, '$1;'); |
| 10789 |
| 10790 // Frame code as the function body. |
| 10791 source = 'function(' + (variable || 'obj') + ') {\n' + |
| 10792 (variable |
| 10793 ? '' |
| 10794 : 'obj || (obj = {});\n' |
| 10795 ) + |
| 10796 "var __t, __p = ''" + |
| 10797 (isEscaping |
| 10798 ? ', __e = _.escape' |
| 10799 : '' |
| 10800 ) + |
| 10801 (isEvaluating |
| 10802 ? ', __j = Array.prototype.join;\n' + |
| 10803 "function print() { __p += __j.call(arguments, '') }\n" |
| 10804 : ';\n' |
| 10805 ) + |
| 10806 source + |
| 10807 'return __p\n}'; |
| 10808 |
| 10809 var result = attempt(function() { |
| 10810 return Function(importsKeys, sourceURL + 'return ' + source).apply(undef
ined, importsValues); |
| 10811 }); |
| 10812 |
| 10813 // Provide the compiled function's source by its `toString` method or |
| 10814 // the `source` property as a convenience for inlining compiled templates. |
| 10815 result.source = source; |
| 10816 if (isError(result)) { |
| 10817 throw result; |
| 10818 } |
| 10819 return result; |
| 10820 } |
| 10821 |
| 10822 /** |
| 10823 * Removes leading and trailing whitespace or specified characters from `str
ing`. |
| 10824 * |
| 10825 * @static |
| 10826 * @memberOf _ |
| 10827 * @category String |
| 10828 * @param {string} [string=''] The string to trim. |
| 10829 * @param {string} [chars=whitespace] The characters to trim. |
| 10830 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 10831 * @returns {string} Returns the trimmed string. |
| 10832 * @example |
| 10833 * |
| 10834 * _.trim(' abc '); |
| 10835 * // => 'abc' |
| 10836 * |
| 10837 * _.trim('-_-abc-_-', '_-'); |
| 10838 * // => 'abc' |
| 10839 * |
| 10840 * _.map([' foo ', ' bar '], _.trim); |
| 10841 * // => ['foo', 'bar'] |
| 10842 */ |
| 10843 function trim(string, chars, guard) { |
| 10844 var value = string; |
| 10845 string = baseToString(string); |
| 10846 if (!string) { |
| 10847 return string; |
| 10848 } |
| 10849 if (guard ? isIterateeCall(value, chars, guard) : chars == null) { |
| 10850 return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string)
+ 1); |
| 10851 } |
| 10852 chars = (chars + ''); |
| 10853 return string.slice(charsLeftIndex(string, chars), charsRightIndex(string,
chars) + 1); |
| 10854 } |
| 10855 |
| 10856 /** |
| 10857 * Removes leading whitespace or specified characters from `string`. |
| 10858 * |
| 10859 * @static |
| 10860 * @memberOf _ |
| 10861 * @category String |
| 10862 * @param {string} [string=''] The string to trim. |
| 10863 * @param {string} [chars=whitespace] The characters to trim. |
| 10864 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 10865 * @returns {string} Returns the trimmed string. |
| 10866 * @example |
| 10867 * |
| 10868 * _.trimLeft(' abc '); |
| 10869 * // => 'abc ' |
| 10870 * |
| 10871 * _.trimLeft('-_-abc-_-', '_-'); |
| 10872 * // => 'abc-_-' |
| 10873 */ |
| 10874 function trimLeft(string, chars, guard) { |
| 10875 var value = string; |
| 10876 string = baseToString(string); |
| 10877 if (!string) { |
| 10878 return string; |
| 10879 } |
| 10880 if (guard ? isIterateeCall(value, chars, guard) : chars == null) { |
| 10881 return string.slice(trimmedLeftIndex(string)); |
| 10882 } |
| 10883 return string.slice(charsLeftIndex(string, (chars + ''))); |
| 10884 } |
| 10885 |
| 10886 /** |
| 10887 * Removes trailing whitespace or specified characters from `string`. |
| 10888 * |
| 10889 * @static |
| 10890 * @memberOf _ |
| 10891 * @category String |
| 10892 * @param {string} [string=''] The string to trim. |
| 10893 * @param {string} [chars=whitespace] The characters to trim. |
| 10894 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 10895 * @returns {string} Returns the trimmed string. |
| 10896 * @example |
| 10897 * |
| 10898 * _.trimRight(' abc '); |
| 10899 * // => ' abc' |
| 10900 * |
| 10901 * _.trimRight('-_-abc-_-', '_-'); |
| 10902 * // => '-_-abc' |
| 10903 */ |
| 10904 function trimRight(string, chars, guard) { |
| 10905 var value = string; |
| 10906 string = baseToString(string); |
| 10907 if (!string) { |
| 10908 return string; |
| 10909 } |
| 10910 if (guard ? isIterateeCall(value, chars, guard) : chars == null) { |
| 10911 return string.slice(0, trimmedRightIndex(string) + 1); |
| 10912 } |
| 10913 return string.slice(0, charsRightIndex(string, (chars + '')) + 1); |
| 10914 } |
| 10915 |
| 10916 /** |
| 10917 * Truncates `string` if it's longer than the given maximum string length. |
| 10918 * The last characters of the truncated string are replaced with the omissio
n |
| 10919 * string which defaults to "...". |
| 10920 * |
| 10921 * @static |
| 10922 * @memberOf _ |
| 10923 * @category String |
| 10924 * @param {string} [string=''] The string to truncate. |
| 10925 * @param {Object|number} [options] The options object or maximum string len
gth. |
| 10926 * @param {number} [options.length=30] The maximum string length. |
| 10927 * @param {string} [options.omission='...'] The string to indicate text is o
mitted. |
| 10928 * @param {RegExp|string} [options.separator] The separator pattern to trunc
ate to. |
| 10929 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 10930 * @returns {string} Returns the truncated string. |
| 10931 * @example |
| 10932 * |
| 10933 * _.trunc('hi-diddly-ho there, neighborino'); |
| 10934 * // => 'hi-diddly-ho there, neighbo...' |
| 10935 * |
| 10936 * _.trunc('hi-diddly-ho there, neighborino', 24); |
| 10937 * // => 'hi-diddly-ho there, n...' |
| 10938 * |
| 10939 * _.trunc('hi-diddly-ho there, neighborino', { |
| 10940 * 'length': 24, |
| 10941 * 'separator': ' ' |
| 10942 * }); |
| 10943 * // => 'hi-diddly-ho there,...' |
| 10944 * |
| 10945 * _.trunc('hi-diddly-ho there, neighborino', { |
| 10946 * 'length': 24, |
| 10947 * 'separator': /,? +/ |
| 10948 * }); |
| 10949 * // => 'hi-diddly-ho there...' |
| 10950 * |
| 10951 * _.trunc('hi-diddly-ho there, neighborino', { |
| 10952 * 'omission': ' [...]' |
| 10953 * }); |
| 10954 * // => 'hi-diddly-ho there, neig [...]' |
| 10955 */ |
| 10956 function trunc(string, options, guard) { |
| 10957 if (guard && isIterateeCall(string, options, guard)) { |
| 10958 options = undefined; |
| 10959 } |
| 10960 var length = DEFAULT_TRUNC_LENGTH, |
| 10961 omission = DEFAULT_TRUNC_OMISSION; |
| 10962 |
| 10963 if (options != null) { |
| 10964 if (isObject(options)) { |
| 10965 var separator = 'separator' in options ? options.separator : separator
; |
| 10966 length = 'length' in options ? (+options.length || 0) : length; |
| 10967 omission = 'omission' in options ? baseToString(options.omission) : om
ission; |
| 10968 } else { |
| 10969 length = +options || 0; |
| 10970 } |
| 10971 } |
| 10972 string = baseToString(string); |
| 10973 if (length >= string.length) { |
| 10974 return string; |
| 10975 } |
| 10976 var end = length - omission.length; |
| 10977 if (end < 1) { |
| 10978 return omission; |
| 10979 } |
| 10980 var result = string.slice(0, end); |
| 10981 if (separator == null) { |
| 10982 return result + omission; |
| 10983 } |
| 10984 if (isRegExp(separator)) { |
| 10985 if (string.slice(end).search(separator)) { |
| 10986 var match, |
| 10987 newEnd, |
| 10988 substring = string.slice(0, end); |
| 10989 |
| 10990 if (!separator.global) { |
| 10991 separator = RegExp(separator.source, (reFlags.exec(separator) || '')
+ 'g'); |
| 10992 } |
| 10993 separator.lastIndex = 0; |
| 10994 while ((match = separator.exec(substring))) { |
| 10995 newEnd = match.index; |
| 10996 } |
| 10997 result = result.slice(0, newEnd == null ? end : newEnd); |
| 10998 } |
| 10999 } else if (string.indexOf(separator, end) != end) { |
| 11000 var index = result.lastIndexOf(separator); |
| 11001 if (index > -1) { |
| 11002 result = result.slice(0, index); |
| 11003 } |
| 11004 } |
| 11005 return result + omission; |
| 11006 } |
| 11007 |
| 11008 /** |
| 11009 * The inverse of `_.escape`; this method converts the HTML entities |
| 11010 * `&`, `<`, `>`, `"`, `'`, and ``` in `string` to th
eir |
| 11011 * corresponding characters. |
| 11012 * |
| 11013 * **Note:** No other HTML entities are unescaped. To unescape additional HT
ML |
| 11014 * entities use a third-party library like [_he_](https://mths.be/he). |
| 11015 * |
| 11016 * @static |
| 11017 * @memberOf _ |
| 11018 * @category String |
| 11019 * @param {string} [string=''] The string to unescape. |
| 11020 * @returns {string} Returns the unescaped string. |
| 11021 * @example |
| 11022 * |
| 11023 * _.unescape('fred, barney, & pebbles'); |
| 11024 * // => 'fred, barney, & pebbles' |
| 11025 */ |
| 11026 function unescape(string) { |
| 11027 string = baseToString(string); |
| 11028 return (string && reHasEscapedHtml.test(string)) |
| 11029 ? string.replace(reEscapedHtml, unescapeHtmlChar) |
| 11030 : string; |
| 11031 } |
| 11032 |
| 11033 /** |
| 11034 * Splits `string` into an array of its words. |
| 11035 * |
| 11036 * @static |
| 11037 * @memberOf _ |
| 11038 * @category String |
| 11039 * @param {string} [string=''] The string to inspect. |
| 11040 * @param {RegExp|string} [pattern] The pattern to match words. |
| 11041 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 11042 * @returns {Array} Returns the words of `string`. |
| 11043 * @example |
| 11044 * |
| 11045 * _.words('fred, barney, & pebbles'); |
| 11046 * // => ['fred', 'barney', 'pebbles'] |
| 11047 * |
| 11048 * _.words('fred, barney, & pebbles', /[^, ]+/g); |
| 11049 * // => ['fred', 'barney', '&', 'pebbles'] |
| 11050 */ |
| 11051 function words(string, pattern, guard) { |
| 11052 if (guard && isIterateeCall(string, pattern, guard)) { |
| 11053 pattern = undefined; |
| 11054 } |
| 11055 string = baseToString(string); |
| 11056 return string.match(pattern || reWords) || []; |
| 11057 } |
| 11058 |
| 11059 /*------------------------------------------------------------------------*/ |
| 11060 |
| 11061 /** |
| 11062 * Attempts to invoke `func`, returning either the result or the caught erro
r |
| 11063 * object. Any additional arguments are provided to `func` when it's invoked
. |
| 11064 * |
| 11065 * @static |
| 11066 * @memberOf _ |
| 11067 * @category Utility |
| 11068 * @param {Function} func The function to attempt. |
| 11069 * @returns {*} Returns the `func` result or error object. |
| 11070 * @example |
| 11071 * |
| 11072 * // avoid throwing errors for invalid selectors |
| 11073 * var elements = _.attempt(function(selector) { |
| 11074 * return document.querySelectorAll(selector); |
| 11075 * }, '>_>'); |
| 11076 * |
| 11077 * if (_.isError(elements)) { |
| 11078 * elements = []; |
| 11079 * } |
| 11080 */ |
| 11081 var attempt = restParam(function(func, args) { |
| 11082 try { |
| 11083 return func.apply(undefined, args); |
| 11084 } catch(e) { |
| 11085 return isError(e) ? e : new Error(e); |
| 11086 } |
| 11087 }); |
| 11088 |
| 11089 /** |
| 11090 * Creates a function that invokes `func` with the `this` binding of `thisAr
g` |
| 11091 * and arguments of the created function. If `func` is a property name the |
| 11092 * created callback returns the property value for a given element. If `func
` |
| 11093 * is an object the created callback returns `true` for elements that contai
n |
| 11094 * the equivalent object properties, otherwise it returns `false`. |
| 11095 * |
| 11096 * @static |
| 11097 * @memberOf _ |
| 11098 * @alias iteratee |
| 11099 * @category Utility |
| 11100 * @param {*} [func=_.identity] The value to convert to a callback. |
| 11101 * @param {*} [thisArg] The `this` binding of `func`. |
| 11102 * @param- {Object} [guard] Enables use as a callback for functions like `_.
map`. |
| 11103 * @returns {Function} Returns the callback. |
| 11104 * @example |
| 11105 * |
| 11106 * var users = [ |
| 11107 * { 'user': 'barney', 'age': 36 }, |
| 11108 * { 'user': 'fred', 'age': 40 } |
| 11109 * ]; |
| 11110 * |
| 11111 * // wrap to create custom callback shorthands |
| 11112 * _.callback = _.wrap(_.callback, function(callback, func, thisArg) { |
| 11113 * var match = /^(.+?)__([gl]t)(.+)$/.exec(func); |
| 11114 * if (!match) { |
| 11115 * return callback(func, thisArg); |
| 11116 * } |
| 11117 * return function(object) { |
| 11118 * return match[2] == 'gt' |
| 11119 * ? object[match[1]] > match[3] |
| 11120 * : object[match[1]] < match[3]; |
| 11121 * }; |
| 11122 * }); |
| 11123 * |
| 11124 * _.filter(users, 'age__gt36'); |
| 11125 * // => [{ 'user': 'fred', 'age': 40 }] |
| 11126 */ |
| 11127 function callback(func, thisArg, guard) { |
| 11128 if (guard && isIterateeCall(func, thisArg, guard)) { |
| 11129 thisArg = undefined; |
| 11130 } |
| 11131 return isObjectLike(func) |
| 11132 ? matches(func) |
| 11133 : baseCallback(func, thisArg); |
| 11134 } |
| 11135 |
| 11136 /** |
| 11137 * Creates a function that returns `value`. |
| 11138 * |
| 11139 * @static |
| 11140 * @memberOf _ |
| 11141 * @category Utility |
| 11142 * @param {*} value The value to return from the new function. |
| 11143 * @returns {Function} Returns the new function. |
| 11144 * @example |
| 11145 * |
| 11146 * var object = { 'user': 'fred' }; |
| 11147 * var getter = _.constant(object); |
| 11148 * |
| 11149 * getter() === object; |
| 11150 * // => true |
| 11151 */ |
| 11152 function constant(value) { |
| 11153 return function() { |
| 11154 return value; |
| 11155 }; |
| 11156 } |
| 11157 |
| 11158 /** |
| 11159 * This method returns the first argument provided to it. |
| 11160 * |
| 11161 * @static |
| 11162 * @memberOf _ |
| 11163 * @category Utility |
| 11164 * @param {*} value Any value. |
| 11165 * @returns {*} Returns `value`. |
| 11166 * @example |
| 11167 * |
| 11168 * var object = { 'user': 'fred' }; |
| 11169 * |
| 11170 * _.identity(object) === object; |
| 11171 * // => true |
| 11172 */ |
| 11173 function identity(value) { |
| 11174 return value; |
| 11175 } |
| 11176 |
| 11177 /** |
| 11178 * Creates a function that performs a deep comparison between a given object |
| 11179 * and `source`, returning `true` if the given object has equivalent propert
y |
| 11180 * values, else `false`. |
| 11181 * |
| 11182 * **Note:** This method supports comparing arrays, booleans, `Date` objects
, |
| 11183 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
| 11184 * their own, not inherited, enumerable properties. For comparing a single |
| 11185 * own or inherited property value see `_.matchesProperty`. |
| 11186 * |
| 11187 * @static |
| 11188 * @memberOf _ |
| 11189 * @category Utility |
| 11190 * @param {Object} source The object of property values to match. |
| 11191 * @returns {Function} Returns the new function. |
| 11192 * @example |
| 11193 * |
| 11194 * var users = [ |
| 11195 * { 'user': 'barney', 'age': 36, 'active': true }, |
| 11196 * { 'user': 'fred', 'age': 40, 'active': false } |
| 11197 * ]; |
| 11198 * |
| 11199 * _.filter(users, _.matches({ 'age': 40, 'active': false })); |
| 11200 * // => [{ 'user': 'fred', 'age': 40, 'active': false }] |
| 11201 */ |
| 11202 function matches(source) { |
| 11203 return baseMatches(baseClone(source, true)); |
| 11204 } |
| 11205 |
| 11206 /** |
| 11207 * Creates a function that compares the property value of `path` on a given |
| 11208 * object to `value`. |
| 11209 * |
| 11210 * **Note:** This method supports comparing arrays, booleans, `Date` objects
, |
| 11211 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
| 11212 * their own, not inherited, enumerable properties. |
| 11213 * |
| 11214 * @static |
| 11215 * @memberOf _ |
| 11216 * @category Utility |
| 11217 * @param {Array|string} path The path of the property to get. |
| 11218 * @param {*} srcValue The value to match. |
| 11219 * @returns {Function} Returns the new function. |
| 11220 * @example |
| 11221 * |
| 11222 * var users = [ |
| 11223 * { 'user': 'barney' }, |
| 11224 * { 'user': 'fred' } |
| 11225 * ]; |
| 11226 * |
| 11227 * _.find(users, _.matchesProperty('user', 'fred')); |
| 11228 * // => { 'user': 'fred' } |
| 11229 */ |
| 11230 function matchesProperty(path, srcValue) { |
| 11231 return baseMatchesProperty(path, baseClone(srcValue, true)); |
| 11232 } |
| 11233 |
| 11234 /** |
| 11235 * Creates a function that invokes the method at `path` on a given object. |
| 11236 * Any additional arguments are provided to the invoked method. |
| 11237 * |
| 11238 * @static |
| 11239 * @memberOf _ |
| 11240 * @category Utility |
| 11241 * @param {Array|string} path The path of the method to invoke. |
| 11242 * @param {...*} [args] The arguments to invoke the method with. |
| 11243 * @returns {Function} Returns the new function. |
| 11244 * @example |
| 11245 * |
| 11246 * var objects = [ |
| 11247 * { 'a': { 'b': { 'c': _.constant(2) } } }, |
| 11248 * { 'a': { 'b': { 'c': _.constant(1) } } } |
| 11249 * ]; |
| 11250 * |
| 11251 * _.map(objects, _.method('a.b.c')); |
| 11252 * // => [2, 1] |
| 11253 * |
| 11254 * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); |
| 11255 * // => [1, 2] |
| 11256 */ |
| 11257 var method = restParam(function(path, args) { |
| 11258 return function(object) { |
| 11259 return invokePath(object, path, args); |
| 11260 }; |
| 11261 }); |
| 11262 |
| 11263 /** |
| 11264 * The opposite of `_.method`; this method creates a function that invokes |
| 11265 * the method at a given path on `object`. Any additional arguments are |
| 11266 * provided to the invoked method. |
| 11267 * |
| 11268 * @static |
| 11269 * @memberOf _ |
| 11270 * @category Utility |
| 11271 * @param {Object} object The object to query. |
| 11272 * @param {...*} [args] The arguments to invoke the method with. |
| 11273 * @returns {Function} Returns the new function. |
| 11274 * @example |
| 11275 * |
| 11276 * var array = _.times(3, _.constant), |
| 11277 * object = { 'a': array, 'b': array, 'c': array }; |
| 11278 * |
| 11279 * _.map(['a[2]', 'c[0]'], _.methodOf(object)); |
| 11280 * // => [2, 0] |
| 11281 * |
| 11282 * _.map([['a', '2'], ['c', '0']], _.methodOf(object)); |
| 11283 * // => [2, 0] |
| 11284 */ |
| 11285 var methodOf = restParam(function(object, args) { |
| 11286 return function(path) { |
| 11287 return invokePath(object, path, args); |
| 11288 }; |
| 11289 }); |
| 11290 |
| 11291 /** |
| 11292 * Adds all own enumerable function properties of a source object to the |
| 11293 * destination object. If `object` is a function then methods are added to |
| 11294 * its prototype as well. |
| 11295 * |
| 11296 * **Note:** Use `_.runInContext` to create a pristine `lodash` function to |
| 11297 * avoid conflicts caused by modifying the original. |
| 11298 * |
| 11299 * @static |
| 11300 * @memberOf _ |
| 11301 * @category Utility |
| 11302 * @param {Function|Object} [object=lodash] The destination object. |
| 11303 * @param {Object} source The object of functions to add. |
| 11304 * @param {Object} [options] The options object. |
| 11305 * @param {boolean} [options.chain=true] Specify whether the functions added |
| 11306 * are chainable. |
| 11307 * @returns {Function|Object} Returns `object`. |
| 11308 * @example |
| 11309 * |
| 11310 * function vowels(string) { |
| 11311 * return _.filter(string, function(v) { |
| 11312 * return /[aeiou]/i.test(v); |
| 11313 * }); |
| 11314 * } |
| 11315 * |
| 11316 * _.mixin({ 'vowels': vowels }); |
| 11317 * _.vowels('fred'); |
| 11318 * // => ['e'] |
| 11319 * |
| 11320 * _('fred').vowels().value(); |
| 11321 * // => ['e'] |
| 11322 * |
| 11323 * _.mixin({ 'vowels': vowels }, { 'chain': false }); |
| 11324 * _('fred').vowels(); |
| 11325 * // => ['e'] |
| 11326 */ |
| 11327 function mixin(object, source, options) { |
| 11328 if (options == null) { |
| 11329 var isObj = isObject(source), |
| 11330 props = isObj ? keys(source) : undefined, |
| 11331 methodNames = (props && props.length) ? baseFunctions(source, props)
: undefined; |
| 11332 |
| 11333 if (!(methodNames ? methodNames.length : isObj)) { |
| 11334 methodNames = false; |
| 11335 options = source; |
| 11336 source = object; |
| 11337 object = this; |
| 11338 } |
| 11339 } |
| 11340 if (!methodNames) { |
| 11341 methodNames = baseFunctions(source, keys(source)); |
| 11342 } |
| 11343 var chain = true, |
| 11344 index = -1, |
| 11345 isFunc = isFunction(object), |
| 11346 length = methodNames.length; |
| 11347 |
| 11348 if (options === false) { |
| 11349 chain = false; |
| 11350 } else if (isObject(options) && 'chain' in options) { |
| 11351 chain = options.chain; |
| 11352 } |
| 11353 while (++index < length) { |
| 11354 var methodName = methodNames[index], |
| 11355 func = source[methodName]; |
| 11356 |
| 11357 object[methodName] = func; |
| 11358 if (isFunc) { |
| 11359 object.prototype[methodName] = (function(func) { |
| 11360 return function() { |
| 11361 var chainAll = this.__chain__; |
| 11362 if (chain || chainAll) { |
| 11363 var result = object(this.__wrapped__), |
| 11364 actions = result.__actions__ = arrayCopy(this.__actions__); |
| 11365 |
| 11366 actions.push({ 'func': func, 'args': arguments, 'thisArg': objec
t }); |
| 11367 result.__chain__ = chainAll; |
| 11368 return result; |
| 11369 } |
| 11370 return func.apply(object, arrayPush([this.value()], arguments)); |
| 11371 }; |
| 11372 }(func)); |
| 11373 } |
| 11374 } |
| 11375 return object; |
| 11376 } |
| 11377 |
| 11378 /** |
| 11379 * Reverts the `_` variable to its previous value and returns a reference to |
| 11380 * the `lodash` function. |
| 11381 * |
| 11382 * @static |
| 11383 * @memberOf _ |
| 11384 * @category Utility |
| 11385 * @returns {Function} Returns the `lodash` function. |
| 11386 * @example |
| 11387 * |
| 11388 * var lodash = _.noConflict(); |
| 11389 */ |
| 11390 function noConflict() { |
| 11391 root._ = oldDash; |
| 11392 return this; |
| 11393 } |
| 11394 |
| 11395 /** |
| 11396 * A no-operation function that returns `undefined` regardless of the |
| 11397 * arguments it receives. |
| 11398 * |
| 11399 * @static |
| 11400 * @memberOf _ |
| 11401 * @category Utility |
| 11402 * @example |
| 11403 * |
| 11404 * var object = { 'user': 'fred' }; |
| 11405 * |
| 11406 * _.noop(object) === undefined; |
| 11407 * // => true |
| 11408 */ |
| 11409 function noop() { |
| 11410 // No operation performed. |
| 11411 } |
| 11412 |
| 11413 /** |
| 11414 * Creates a function that returns the property value at `path` on a |
| 11415 * given object. |
| 11416 * |
| 11417 * @static |
| 11418 * @memberOf _ |
| 11419 * @category Utility |
| 11420 * @param {Array|string} path The path of the property to get. |
| 11421 * @returns {Function} Returns the new function. |
| 11422 * @example |
| 11423 * |
| 11424 * var objects = [ |
| 11425 * { 'a': { 'b': { 'c': 2 } } }, |
| 11426 * { 'a': { 'b': { 'c': 1 } } } |
| 11427 * ]; |
| 11428 * |
| 11429 * _.map(objects, _.property('a.b.c')); |
| 11430 * // => [2, 1] |
| 11431 * |
| 11432 * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); |
| 11433 * // => [1, 2] |
| 11434 */ |
| 11435 function property(path) { |
| 11436 return isKey(path) ? baseProperty(path) : basePropertyDeep(path); |
| 11437 } |
| 11438 |
| 11439 /** |
| 11440 * The opposite of `_.property`; this method creates a function that returns |
| 11441 * the property value at a given path on `object`. |
| 11442 * |
| 11443 * @static |
| 11444 * @memberOf _ |
| 11445 * @category Utility |
| 11446 * @param {Object} object The object to query. |
| 11447 * @returns {Function} Returns the new function. |
| 11448 * @example |
| 11449 * |
| 11450 * var array = [0, 1, 2], |
| 11451 * object = { 'a': array, 'b': array, 'c': array }; |
| 11452 * |
| 11453 * _.map(['a[2]', 'c[0]'], _.propertyOf(object)); |
| 11454 * // => [2, 0] |
| 11455 * |
| 11456 * _.map([['a', '2'], ['c', '0']], _.propertyOf(object)); |
| 11457 * // => [2, 0] |
| 11458 */ |
| 11459 function propertyOf(object) { |
| 11460 return function(path) { |
| 11461 return baseGet(object, toPath(path), (path + '')); |
| 11462 }; |
| 11463 } |
| 11464 |
| 11465 /** |
| 11466 * Creates an array of numbers (positive and/or negative) progressing from |
| 11467 * `start` up to, but not including, `end`. If `end` is not specified it's |
| 11468 * set to `start` with `start` then set to `0`. If `end` is less than `start
` |
| 11469 * a zero-length range is created unless a negative `step` is specified. |
| 11470 * |
| 11471 * @static |
| 11472 * @memberOf _ |
| 11473 * @category Utility |
| 11474 * @param {number} [start=0] The start of the range. |
| 11475 * @param {number} end The end of the range. |
| 11476 * @param {number} [step=1] The value to increment or decrement by. |
| 11477 * @returns {Array} Returns the new array of numbers. |
| 11478 * @example |
| 11479 * |
| 11480 * _.range(4); |
| 11481 * // => [0, 1, 2, 3] |
| 11482 * |
| 11483 * _.range(1, 5); |
| 11484 * // => [1, 2, 3, 4] |
| 11485 * |
| 11486 * _.range(0, 20, 5); |
| 11487 * // => [0, 5, 10, 15] |
| 11488 * |
| 11489 * _.range(0, -4, -1); |
| 11490 * // => [0, -1, -2, -3] |
| 11491 * |
| 11492 * _.range(1, 4, 0); |
| 11493 * // => [1, 1, 1] |
| 11494 * |
| 11495 * _.range(0); |
| 11496 * // => [] |
| 11497 */ |
| 11498 function range(start, end, step) { |
| 11499 if (step && isIterateeCall(start, end, step)) { |
| 11500 end = step = undefined; |
| 11501 } |
| 11502 start = +start || 0; |
| 11503 step = step == null ? 1 : (+step || 0); |
| 11504 |
| 11505 if (end == null) { |
| 11506 end = start; |
| 11507 start = 0; |
| 11508 } else { |
| 11509 end = +end || 0; |
| 11510 } |
| 11511 // Use `Array(length)` so engines like Chakra and V8 avoid slower modes. |
| 11512 // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details. |
| 11513 var index = -1, |
| 11514 length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), |
| 11515 result = Array(length); |
| 11516 |
| 11517 while (++index < length) { |
| 11518 result[index] = start; |
| 11519 start += step; |
| 11520 } |
| 11521 return result; |
| 11522 } |
| 11523 |
| 11524 /** |
| 11525 * Invokes the iteratee function `n` times, returning an array of the result
s |
| 11526 * of each invocation. The `iteratee` is bound to `thisArg` and invoked with |
| 11527 * one argument; (index). |
| 11528 * |
| 11529 * @static |
| 11530 * @memberOf _ |
| 11531 * @category Utility |
| 11532 * @param {number} n The number of times to invoke `iteratee`. |
| 11533 * @param {Function} [iteratee=_.identity] The function invoked per iteratio
n. |
| 11534 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 11535 * @returns {Array} Returns the array of results. |
| 11536 * @example |
| 11537 * |
| 11538 * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false)); |
| 11539 * // => [3, 6, 4] |
| 11540 * |
| 11541 * _.times(3, function(n) { |
| 11542 * mage.castSpell(n); |
| 11543 * }); |
| 11544 * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `
2` |
| 11545 * |
| 11546 * _.times(3, function(n) { |
| 11547 * this.cast(n); |
| 11548 * }, mage); |
| 11549 * // => also invokes `mage.castSpell(n)` three times |
| 11550 */ |
| 11551 function times(n, iteratee, thisArg) { |
| 11552 n = nativeFloor(n); |
| 11553 |
| 11554 // Exit early to avoid a JSC JIT bug in Safari 8 |
| 11555 // where `Array(0)` is treated as `Array(1)`. |
| 11556 if (n < 1 || !nativeIsFinite(n)) { |
| 11557 return []; |
| 11558 } |
| 11559 var index = -1, |
| 11560 result = Array(nativeMin(n, MAX_ARRAY_LENGTH)); |
| 11561 |
| 11562 iteratee = bindCallback(iteratee, thisArg, 1); |
| 11563 while (++index < n) { |
| 11564 if (index < MAX_ARRAY_LENGTH) { |
| 11565 result[index] = iteratee(index); |
| 11566 } else { |
| 11567 iteratee(index); |
| 11568 } |
| 11569 } |
| 11570 return result; |
| 11571 } |
| 11572 |
| 11573 /** |
| 11574 * Generates a unique ID. If `prefix` is provided the ID is appended to it. |
| 11575 * |
| 11576 * @static |
| 11577 * @memberOf _ |
| 11578 * @category Utility |
| 11579 * @param {string} [prefix] The value to prefix the ID with. |
| 11580 * @returns {string} Returns the unique ID. |
| 11581 * @example |
| 11582 * |
| 11583 * _.uniqueId('contact_'); |
| 11584 * // => 'contact_104' |
| 11585 * |
| 11586 * _.uniqueId(); |
| 11587 * // => '105' |
| 11588 */ |
| 11589 function uniqueId(prefix) { |
| 11590 var id = ++idCounter; |
| 11591 return baseToString(prefix) + id; |
| 11592 } |
| 11593 |
| 11594 /*------------------------------------------------------------------------*/ |
| 11595 |
| 11596 /** |
| 11597 * Adds two numbers. |
| 11598 * |
| 11599 * @static |
| 11600 * @memberOf _ |
| 11601 * @category Math |
| 11602 * @param {number} augend The first number to add. |
| 11603 * @param {number} addend The second number to add. |
| 11604 * @returns {number} Returns the sum. |
| 11605 * @example |
| 11606 * |
| 11607 * _.add(6, 4); |
| 11608 * // => 10 |
| 11609 */ |
| 11610 function add(augend, addend) { |
| 11611 return (+augend || 0) + (+addend || 0); |
| 11612 } |
| 11613 |
| 11614 /** |
| 11615 * Calculates `n` rounded up to `precision`. |
| 11616 * |
| 11617 * @static |
| 11618 * @memberOf _ |
| 11619 * @category Math |
| 11620 * @param {number} n The number to round up. |
| 11621 * @param {number} [precision=0] The precision to round up to. |
| 11622 * @returns {number} Returns the rounded up number. |
| 11623 * @example |
| 11624 * |
| 11625 * _.ceil(4.006); |
| 11626 * // => 5 |
| 11627 * |
| 11628 * _.ceil(6.004, 2); |
| 11629 * // => 6.01 |
| 11630 * |
| 11631 * _.ceil(6040, -2); |
| 11632 * // => 6100 |
| 11633 */ |
| 11634 var ceil = createRound('ceil'); |
| 11635 |
| 11636 /** |
| 11637 * Calculates `n` rounded down to `precision`. |
| 11638 * |
| 11639 * @static |
| 11640 * @memberOf _ |
| 11641 * @category Math |
| 11642 * @param {number} n The number to round down. |
| 11643 * @param {number} [precision=0] The precision to round down to. |
| 11644 * @returns {number} Returns the rounded down number. |
| 11645 * @example |
| 11646 * |
| 11647 * _.floor(4.006); |
| 11648 * // => 4 |
| 11649 * |
| 11650 * _.floor(0.046, 2); |
| 11651 * // => 0.04 |
| 11652 * |
| 11653 * _.floor(4060, -2); |
| 11654 * // => 4000 |
| 11655 */ |
| 11656 var floor = createRound('floor'); |
| 11657 |
| 11658 /** |
| 11659 * Gets the maximum value of `collection`. If `collection` is empty or false
y |
| 11660 * `-Infinity` is returned. If an iteratee function is provided it's invoked |
| 11661 * for each value in `collection` to generate the criterion by which the val
ue |
| 11662 * is ranked. The `iteratee` is bound to `thisArg` and invoked with three |
| 11663 * arguments: (value, index, collection). |
| 11664 * |
| 11665 * If a property name is provided for `iteratee` the created `_.property` |
| 11666 * style callback returns the property value of the given element. |
| 11667 * |
| 11668 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 11669 * style callback returns `true` for elements that have a matching property |
| 11670 * value, else `false`. |
| 11671 * |
| 11672 * If an object is provided for `iteratee` the created `_.matches` style |
| 11673 * callback returns `true` for elements that have the properties of the give
n |
| 11674 * object, else `false`. |
| 11675 * |
| 11676 * @static |
| 11677 * @memberOf _ |
| 11678 * @category Math |
| 11679 * @param {Array|Object|string} collection The collection to iterate over. |
| 11680 * @param {Function|Object|string} [iteratee] The function invoked per itera
tion. |
| 11681 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 11682 * @returns {*} Returns the maximum value. |
| 11683 * @example |
| 11684 * |
| 11685 * _.max([4, 2, 8, 6]); |
| 11686 * // => 8 |
| 11687 * |
| 11688 * _.max([]); |
| 11689 * // => -Infinity |
| 11690 * |
| 11691 * var users = [ |
| 11692 * { 'user': 'barney', 'age': 36 }, |
| 11693 * { 'user': 'fred', 'age': 40 } |
| 11694 * ]; |
| 11695 * |
| 11696 * _.max(users, function(chr) { |
| 11697 * return chr.age; |
| 11698 * }); |
| 11699 * // => { 'user': 'fred', 'age': 40 } |
| 11700 * |
| 11701 * // using the `_.property` callback shorthand |
| 11702 * _.max(users, 'age'); |
| 11703 * // => { 'user': 'fred', 'age': 40 } |
| 11704 */ |
| 11705 var max = createExtremum(gt, NEGATIVE_INFINITY); |
| 11706 |
| 11707 /** |
| 11708 * Gets the minimum value of `collection`. If `collection` is empty or false
y |
| 11709 * `Infinity` is returned. If an iteratee function is provided it's invoked |
| 11710 * for each value in `collection` to generate the criterion by which the val
ue |
| 11711 * is ranked. The `iteratee` is bound to `thisArg` and invoked with three |
| 11712 * arguments: (value, index, collection). |
| 11713 * |
| 11714 * If a property name is provided for `iteratee` the created `_.property` |
| 11715 * style callback returns the property value of the given element. |
| 11716 * |
| 11717 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 11718 * style callback returns `true` for elements that have a matching property |
| 11719 * value, else `false`. |
| 11720 * |
| 11721 * If an object is provided for `iteratee` the created `_.matches` style |
| 11722 * callback returns `true` for elements that have the properties of the give
n |
| 11723 * object, else `false`. |
| 11724 * |
| 11725 * @static |
| 11726 * @memberOf _ |
| 11727 * @category Math |
| 11728 * @param {Array|Object|string} collection The collection to iterate over. |
| 11729 * @param {Function|Object|string} [iteratee] The function invoked per itera
tion. |
| 11730 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 11731 * @returns {*} Returns the minimum value. |
| 11732 * @example |
| 11733 * |
| 11734 * _.min([4, 2, 8, 6]); |
| 11735 * // => 2 |
| 11736 * |
| 11737 * _.min([]); |
| 11738 * // => Infinity |
| 11739 * |
| 11740 * var users = [ |
| 11741 * { 'user': 'barney', 'age': 36 }, |
| 11742 * { 'user': 'fred', 'age': 40 } |
| 11743 * ]; |
| 11744 * |
| 11745 * _.min(users, function(chr) { |
| 11746 * return chr.age; |
| 11747 * }); |
| 11748 * // => { 'user': 'barney', 'age': 36 } |
| 11749 * |
| 11750 * // using the `_.property` callback shorthand |
| 11751 * _.min(users, 'age'); |
| 11752 * // => { 'user': 'barney', 'age': 36 } |
| 11753 */ |
| 11754 var min = createExtremum(lt, POSITIVE_INFINITY); |
| 11755 |
| 11756 /** |
| 11757 * Calculates `n` rounded to `precision`. |
| 11758 * |
| 11759 * @static |
| 11760 * @memberOf _ |
| 11761 * @category Math |
| 11762 * @param {number} n The number to round. |
| 11763 * @param {number} [precision=0] The precision to round to. |
| 11764 * @returns {number} Returns the rounded number. |
| 11765 * @example |
| 11766 * |
| 11767 * _.round(4.006); |
| 11768 * // => 4 |
| 11769 * |
| 11770 * _.round(4.006, 2); |
| 11771 * // => 4.01 |
| 11772 * |
| 11773 * _.round(4060, -2); |
| 11774 * // => 4100 |
| 11775 */ |
| 11776 var round = createRound('round'); |
| 11777 |
| 11778 /** |
| 11779 * Gets the sum of the values in `collection`. |
| 11780 * |
| 11781 * @static |
| 11782 * @memberOf _ |
| 11783 * @category Math |
| 11784 * @param {Array|Object|string} collection The collection to iterate over. |
| 11785 * @param {Function|Object|string} [iteratee] The function invoked per itera
tion. |
| 11786 * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 11787 * @returns {number} Returns the sum. |
| 11788 * @example |
| 11789 * |
| 11790 * _.sum([4, 6]); |
| 11791 * // => 10 |
| 11792 * |
| 11793 * _.sum({ 'a': 4, 'b': 6 }); |
| 11794 * // => 10 |
| 11795 * |
| 11796 * var objects = [ |
| 11797 * { 'n': 4 }, |
| 11798 * { 'n': 6 } |
| 11799 * ]; |
| 11800 * |
| 11801 * _.sum(objects, function(object) { |
| 11802 * return object.n; |
| 11803 * }); |
| 11804 * // => 10 |
| 11805 * |
| 11806 * // using the `_.property` callback shorthand |
| 11807 * _.sum(objects, 'n'); |
| 11808 * // => 10 |
| 11809 */ |
| 11810 function sum(collection, iteratee, thisArg) { |
| 11811 if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
| 11812 iteratee = undefined; |
| 11813 } |
| 11814 iteratee = getCallback(iteratee, thisArg, 3); |
| 11815 return iteratee.length == 1 |
| 11816 ? arraySum(isArray(collection) ? collection : toIterable(collection), it
eratee) |
| 11817 : baseSum(collection, iteratee); |
| 11818 } |
| 11819 |
| 11820 /*------------------------------------------------------------------------*/ |
| 11821 |
| 11822 // Ensure wrappers are instances of `baseLodash`. |
| 11823 lodash.prototype = baseLodash.prototype; |
| 11824 |
| 11825 LodashWrapper.prototype = baseCreate(baseLodash.prototype); |
| 11826 LodashWrapper.prototype.constructor = LodashWrapper; |
| 11827 |
| 11828 LazyWrapper.prototype = baseCreate(baseLodash.prototype); |
| 11829 LazyWrapper.prototype.constructor = LazyWrapper; |
| 11830 |
| 11831 // Add functions to the `Map` cache. |
| 11832 MapCache.prototype['delete'] = mapDelete; |
| 11833 MapCache.prototype.get = mapGet; |
| 11834 MapCache.prototype.has = mapHas; |
| 11835 MapCache.prototype.set = mapSet; |
| 11836 |
| 11837 // Add functions to the `Set` cache. |
| 11838 SetCache.prototype.push = cachePush; |
| 11839 |
| 11840 // Assign cache to `_.memoize`. |
| 11841 memoize.Cache = MapCache; |
| 11842 |
| 11843 // Add functions that return wrapped values when chaining. |
| 11844 lodash.after = after; |
| 11845 lodash.ary = ary; |
| 11846 lodash.assign = assign; |
| 11847 lodash.at = at; |
| 11848 lodash.before = before; |
| 11849 lodash.bind = bind; |
| 11850 lodash.bindAll = bindAll; |
| 11851 lodash.bindKey = bindKey; |
| 11852 lodash.callback = callback; |
| 11853 lodash.chain = chain; |
| 11854 lodash.chunk = chunk; |
| 11855 lodash.compact = compact; |
| 11856 lodash.constant = constant; |
| 11857 lodash.countBy = countBy; |
| 11858 lodash.create = create; |
| 11859 lodash.curry = curry; |
| 11860 lodash.curryRight = curryRight; |
| 11861 lodash.debounce = debounce; |
| 11862 lodash.defaults = defaults; |
| 11863 lodash.defaultsDeep = defaultsDeep; |
| 11864 lodash.defer = defer; |
| 11865 lodash.delay = delay; |
| 11866 lodash.difference = difference; |
| 11867 lodash.drop = drop; |
| 11868 lodash.dropRight = dropRight; |
| 11869 lodash.dropRightWhile = dropRightWhile; |
| 11870 lodash.dropWhile = dropWhile; |
| 11871 lodash.fill = fill; |
| 11872 lodash.filter = filter; |
| 11873 lodash.flatten = flatten; |
| 11874 lodash.flattenDeep = flattenDeep; |
| 11875 lodash.flow = flow; |
| 11876 lodash.flowRight = flowRight; |
| 11877 lodash.forEach = forEach; |
| 11878 lodash.forEachRight = forEachRight; |
| 11879 lodash.forIn = forIn; |
| 11880 lodash.forInRight = forInRight; |
| 11881 lodash.forOwn = forOwn; |
| 11882 lodash.forOwnRight = forOwnRight; |
| 11883 lodash.functions = functions; |
| 11884 lodash.groupBy = groupBy; |
| 11885 lodash.indexBy = indexBy; |
| 11886 lodash.initial = initial; |
| 11887 lodash.intersection = intersection; |
| 11888 lodash.invert = invert; |
| 11889 lodash.invoke = invoke; |
| 11890 lodash.keys = keys; |
| 11891 lodash.keysIn = keysIn; |
| 11892 lodash.map = map; |
| 11893 lodash.mapKeys = mapKeys; |
| 11894 lodash.mapValues = mapValues; |
| 11895 lodash.matches = matches; |
| 11896 lodash.matchesProperty = matchesProperty; |
| 11897 lodash.memoize = memoize; |
| 11898 lodash.merge = merge; |
| 11899 lodash.method = method; |
| 11900 lodash.methodOf = methodOf; |
| 11901 lodash.mixin = mixin; |
| 11902 lodash.modArgs = modArgs; |
| 11903 lodash.negate = negate; |
| 11904 lodash.omit = omit; |
| 11905 lodash.once = once; |
| 11906 lodash.pairs = pairs; |
| 11907 lodash.partial = partial; |
| 11908 lodash.partialRight = partialRight; |
| 11909 lodash.partition = partition; |
| 11910 lodash.pick = pick; |
| 11911 lodash.pluck = pluck; |
| 11912 lodash.property = property; |
| 11913 lodash.propertyOf = propertyOf; |
| 11914 lodash.pull = pull; |
| 11915 lodash.pullAt = pullAt; |
| 11916 lodash.range = range; |
| 11917 lodash.rearg = rearg; |
| 11918 lodash.reject = reject; |
| 11919 lodash.remove = remove; |
| 11920 lodash.rest = rest; |
| 11921 lodash.restParam = restParam; |
| 11922 lodash.set = set; |
| 11923 lodash.shuffle = shuffle; |
| 11924 lodash.slice = slice; |
| 11925 lodash.sortBy = sortBy; |
| 11926 lodash.sortByAll = sortByAll; |
| 11927 lodash.sortByOrder = sortByOrder; |
| 11928 lodash.spread = spread; |
| 11929 lodash.take = take; |
| 11930 lodash.takeRight = takeRight; |
| 11931 lodash.takeRightWhile = takeRightWhile; |
| 11932 lodash.takeWhile = takeWhile; |
| 11933 lodash.tap = tap; |
| 11934 lodash.throttle = throttle; |
| 11935 lodash.thru = thru; |
| 11936 lodash.times = times; |
| 11937 lodash.toArray = toArray; |
| 11938 lodash.toPlainObject = toPlainObject; |
| 11939 lodash.transform = transform; |
| 11940 lodash.union = union; |
| 11941 lodash.uniq = uniq; |
| 11942 lodash.unzip = unzip; |
| 11943 lodash.unzipWith = unzipWith; |
| 11944 lodash.values = values; |
| 11945 lodash.valuesIn = valuesIn; |
| 11946 lodash.where = where; |
| 11947 lodash.without = without; |
| 11948 lodash.wrap = wrap; |
| 11949 lodash.xor = xor; |
| 11950 lodash.zip = zip; |
| 11951 lodash.zipObject = zipObject; |
| 11952 lodash.zipWith = zipWith; |
| 11953 |
| 11954 // Add aliases. |
| 11955 lodash.backflow = flowRight; |
| 11956 lodash.collect = map; |
| 11957 lodash.compose = flowRight; |
| 11958 lodash.each = forEach; |
| 11959 lodash.eachRight = forEachRight; |
| 11960 lodash.extend = assign; |
| 11961 lodash.iteratee = callback; |
| 11962 lodash.methods = functions; |
| 11963 lodash.object = zipObject; |
| 11964 lodash.select = filter; |
| 11965 lodash.tail = rest; |
| 11966 lodash.unique = uniq; |
| 11967 |
| 11968 // Add functions to `lodash.prototype`. |
| 11969 mixin(lodash, lodash); |
| 11970 |
| 11971 /*------------------------------------------------------------------------*/ |
| 11972 |
| 11973 // Add functions that return unwrapped values when chaining. |
| 11974 lodash.add = add; |
| 11975 lodash.attempt = attempt; |
| 11976 lodash.camelCase = camelCase; |
| 11977 lodash.capitalize = capitalize; |
| 11978 lodash.ceil = ceil; |
| 11979 lodash.clone = clone; |
| 11980 lodash.cloneDeep = cloneDeep; |
| 11981 lodash.deburr = deburr; |
| 11982 lodash.endsWith = endsWith; |
| 11983 lodash.escape = escape; |
| 11984 lodash.escapeRegExp = escapeRegExp; |
| 11985 lodash.every = every; |
| 11986 lodash.find = find; |
| 11987 lodash.findIndex = findIndex; |
| 11988 lodash.findKey = findKey; |
| 11989 lodash.findLast = findLast; |
| 11990 lodash.findLastIndex = findLastIndex; |
| 11991 lodash.findLastKey = findLastKey; |
| 11992 lodash.findWhere = findWhere; |
| 11993 lodash.first = first; |
| 11994 lodash.floor = floor; |
| 11995 lodash.get = get; |
| 11996 lodash.gt = gt; |
| 11997 lodash.gte = gte; |
| 11998 lodash.has = has; |
| 11999 lodash.identity = identity; |
| 12000 lodash.includes = includes; |
| 12001 lodash.indexOf = indexOf; |
| 12002 lodash.inRange = inRange; |
| 12003 lodash.isArguments = isArguments; |
| 12004 lodash.isArray = isArray; |
| 12005 lodash.isBoolean = isBoolean; |
| 12006 lodash.isDate = isDate; |
| 12007 lodash.isElement = isElement; |
| 12008 lodash.isEmpty = isEmpty; |
| 12009 lodash.isEqual = isEqual; |
| 12010 lodash.isError = isError; |
| 12011 lodash.isFinite = isFinite; |
| 12012 lodash.isFunction = isFunction; |
| 12013 lodash.isMatch = isMatch; |
| 12014 lodash.isNaN = isNaN; |
| 12015 lodash.isNative = isNative; |
| 12016 lodash.isNull = isNull; |
| 12017 lodash.isNumber = isNumber; |
| 12018 lodash.isObject = isObject; |
| 12019 lodash.isPlainObject = isPlainObject; |
| 12020 lodash.isRegExp = isRegExp; |
| 12021 lodash.isString = isString; |
| 12022 lodash.isTypedArray = isTypedArray; |
| 12023 lodash.isUndefined = isUndefined; |
| 12024 lodash.kebabCase = kebabCase; |
| 12025 lodash.last = last; |
| 12026 lodash.lastIndexOf = lastIndexOf; |
| 12027 lodash.lt = lt; |
| 12028 lodash.lte = lte; |
| 12029 lodash.max = max; |
| 12030 lodash.min = min; |
| 12031 lodash.noConflict = noConflict; |
| 12032 lodash.noop = noop; |
| 12033 lodash.now = now; |
| 12034 lodash.pad = pad; |
| 12035 lodash.padLeft = padLeft; |
| 12036 lodash.padRight = padRight; |
| 12037 lodash.parseInt = parseInt; |
| 12038 lodash.random = random; |
| 12039 lodash.reduce = reduce; |
| 12040 lodash.reduceRight = reduceRight; |
| 12041 lodash.repeat = repeat; |
| 12042 lodash.result = result; |
| 12043 lodash.round = round; |
| 12044 lodash.runInContext = runInContext; |
| 12045 lodash.size = size; |
| 12046 lodash.snakeCase = snakeCase; |
| 12047 lodash.some = some; |
| 12048 lodash.sortedIndex = sortedIndex; |
| 12049 lodash.sortedLastIndex = sortedLastIndex; |
| 12050 lodash.startCase = startCase; |
| 12051 lodash.startsWith = startsWith; |
| 12052 lodash.sum = sum; |
| 12053 lodash.template = template; |
| 12054 lodash.trim = trim; |
| 12055 lodash.trimLeft = trimLeft; |
| 12056 lodash.trimRight = trimRight; |
| 12057 lodash.trunc = trunc; |
| 12058 lodash.unescape = unescape; |
| 12059 lodash.uniqueId = uniqueId; |
| 12060 lodash.words = words; |
| 12061 |
| 12062 // Add aliases. |
| 12063 lodash.all = every; |
| 12064 lodash.any = some; |
| 12065 lodash.contains = includes; |
| 12066 lodash.eq = isEqual; |
| 12067 lodash.detect = find; |
| 12068 lodash.foldl = reduce; |
| 12069 lodash.foldr = reduceRight; |
| 12070 lodash.head = first; |
| 12071 lodash.include = includes; |
| 12072 lodash.inject = reduce; |
| 12073 |
| 12074 mixin(lodash, (function() { |
| 12075 var source = {}; |
| 12076 baseForOwn(lodash, function(func, methodName) { |
| 12077 if (!lodash.prototype[methodName]) { |
| 12078 source[methodName] = func; |
| 12079 } |
| 12080 }); |
| 12081 return source; |
| 12082 }()), false); |
| 12083 |
| 12084 /*------------------------------------------------------------------------*/ |
| 12085 |
| 12086 // Add functions capable of returning wrapped and unwrapped values when chai
ning. |
| 12087 lodash.sample = sample; |
| 12088 |
| 12089 lodash.prototype.sample = function(n) { |
| 12090 if (!this.__chain__ && n == null) { |
| 12091 return sample(this.value()); |
| 12092 } |
| 12093 return this.thru(function(value) { |
| 12094 return sample(value, n); |
| 12095 }); |
| 12096 }; |
| 12097 |
| 12098 /*------------------------------------------------------------------------*/ |
| 12099 |
| 12100 /** |
| 12101 * The semantic version number. |
| 12102 * |
| 12103 * @static |
| 12104 * @memberOf _ |
| 12105 * @type string |
| 12106 */ |
| 12107 lodash.VERSION = VERSION; |
| 12108 |
| 12109 // Assign default placeholders. |
| 12110 arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRigh
t'], function(methodName) { |
| 12111 lodash[methodName].placeholder = lodash; |
| 12112 }); |
| 12113 |
| 12114 // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. |
| 12115 arrayEach(['drop', 'take'], function(methodName, index) { |
| 12116 LazyWrapper.prototype[methodName] = function(n) { |
| 12117 var filtered = this.__filtered__; |
| 12118 if (filtered && !index) { |
| 12119 return new LazyWrapper(this); |
| 12120 } |
| 12121 n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0); |
| 12122 |
| 12123 var result = this.clone(); |
| 12124 if (filtered) { |
| 12125 result.__takeCount__ = nativeMin(result.__takeCount__, n); |
| 12126 } else { |
| 12127 result.__views__.push({ 'size': n, 'type': methodName + (result.__dir_
_ < 0 ? 'Right' : '') }); |
| 12128 } |
| 12129 return result; |
| 12130 }; |
| 12131 |
| 12132 LazyWrapper.prototype[methodName + 'Right'] = function(n) { |
| 12133 return this.reverse()[methodName](n).reverse(); |
| 12134 }; |
| 12135 }); |
| 12136 |
| 12137 // Add `LazyWrapper` methods that accept an `iteratee` value. |
| 12138 arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { |
| 12139 var type = index + 1, |
| 12140 isFilter = type != LAZY_MAP_FLAG; |
| 12141 |
| 12142 LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { |
| 12143 var result = this.clone(); |
| 12144 result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1
), 'type': type }); |
| 12145 result.__filtered__ = result.__filtered__ || isFilter; |
| 12146 return result; |
| 12147 }; |
| 12148 }); |
| 12149 |
| 12150 // Add `LazyWrapper` methods for `_.first` and `_.last`. |
| 12151 arrayEach(['first', 'last'], function(methodName, index) { |
| 12152 var takeName = 'take' + (index ? 'Right' : ''); |
| 12153 |
| 12154 LazyWrapper.prototype[methodName] = function() { |
| 12155 return this[takeName](1).value()[0]; |
| 12156 }; |
| 12157 }); |
| 12158 |
| 12159 // Add `LazyWrapper` methods for `_.initial` and `_.rest`. |
| 12160 arrayEach(['initial', 'rest'], function(methodName, index) { |
| 12161 var dropName = 'drop' + (index ? '' : 'Right'); |
| 12162 |
| 12163 LazyWrapper.prototype[methodName] = function() { |
| 12164 return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); |
| 12165 }; |
| 12166 }); |
| 12167 |
| 12168 // Add `LazyWrapper` methods for `_.pluck` and `_.where`. |
| 12169 arrayEach(['pluck', 'where'], function(methodName, index) { |
| 12170 var operationName = index ? 'filter' : 'map', |
| 12171 createCallback = index ? baseMatches : property; |
| 12172 |
| 12173 LazyWrapper.prototype[methodName] = function(value) { |
| 12174 return this[operationName](createCallback(value)); |
| 12175 }; |
| 12176 }); |
| 12177 |
| 12178 LazyWrapper.prototype.compact = function() { |
| 12179 return this.filter(identity); |
| 12180 }; |
| 12181 |
| 12182 LazyWrapper.prototype.reject = function(predicate, thisArg) { |
| 12183 predicate = getCallback(predicate, thisArg, 1); |
| 12184 return this.filter(function(value) { |
| 12185 return !predicate(value); |
| 12186 }); |
| 12187 }; |
| 12188 |
| 12189 LazyWrapper.prototype.slice = function(start, end) { |
| 12190 start = start == null ? 0 : (+start || 0); |
| 12191 |
| 12192 var result = this; |
| 12193 if (result.__filtered__ && (start > 0 || end < 0)) { |
| 12194 return new LazyWrapper(result); |
| 12195 } |
| 12196 if (start < 0) { |
| 12197 result = result.takeRight(-start); |
| 12198 } else if (start) { |
| 12199 result = result.drop(start); |
| 12200 } |
| 12201 if (end !== undefined) { |
| 12202 end = (+end || 0); |
| 12203 result = end < 0 ? result.dropRight(-end) : result.take(end - start); |
| 12204 } |
| 12205 return result; |
| 12206 }; |
| 12207 |
| 12208 LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) { |
| 12209 return this.reverse().takeWhile(predicate, thisArg).reverse(); |
| 12210 }; |
| 12211 |
| 12212 LazyWrapper.prototype.toArray = function() { |
| 12213 return this.take(POSITIVE_INFINITY); |
| 12214 }; |
| 12215 |
| 12216 // Add `LazyWrapper` methods to `lodash.prototype`. |
| 12217 baseForOwn(LazyWrapper.prototype, function(func, methodName) { |
| 12218 var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), |
| 12219 retUnwrapped = /^(?:first|last)$/.test(methodName), |
| 12220 lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? '
Right' : '')) : methodName]; |
| 12221 |
| 12222 if (!lodashFunc) { |
| 12223 return; |
| 12224 } |
| 12225 lodash.prototype[methodName] = function() { |
| 12226 var args = retUnwrapped ? [1] : arguments, |
| 12227 chainAll = this.__chain__, |
| 12228 value = this.__wrapped__, |
| 12229 isHybrid = !!this.__actions__.length, |
| 12230 isLazy = value instanceof LazyWrapper, |
| 12231 iteratee = args[0], |
| 12232 useLazy = isLazy || isArray(value); |
| 12233 |
| 12234 if (useLazy && checkIteratee && typeof iteratee == 'function' && iterate
e.length != 1) { |
| 12235 // Avoid lazy use if the iteratee has a "length" value other than `1`. |
| 12236 isLazy = useLazy = false; |
| 12237 } |
| 12238 var interceptor = function(value) { |
| 12239 return (retUnwrapped && chainAll) |
| 12240 ? lodashFunc(value, 1)[0] |
| 12241 : lodashFunc.apply(undefined, arrayPush([value], args)); |
| 12242 }; |
| 12243 |
| 12244 var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined
}, |
| 12245 onlyLazy = isLazy && !isHybrid; |
| 12246 |
| 12247 if (retUnwrapped && !chainAll) { |
| 12248 if (onlyLazy) { |
| 12249 value = value.clone(); |
| 12250 value.__actions__.push(action); |
| 12251 return func.call(value); |
| 12252 } |
| 12253 return lodashFunc.call(undefined, this.value())[0]; |
| 12254 } |
| 12255 if (!retUnwrapped && useLazy) { |
| 12256 value = onlyLazy ? value : new LazyWrapper(this); |
| 12257 var result = func.apply(value, args); |
| 12258 result.__actions__.push(action); |
| 12259 return new LodashWrapper(result, chainAll); |
| 12260 } |
| 12261 return this.thru(interceptor); |
| 12262 }; |
| 12263 }); |
| 12264 |
| 12265 // Add `Array` and `String` methods to `lodash.prototype`. |
| 12266 arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'spl
it', 'unshift'], function(methodName) { |
| 12267 var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayPr
oto)[methodName], |
| 12268 chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru
', |
| 12269 retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName); |
| 12270 |
| 12271 lodash.prototype[methodName] = function() { |
| 12272 var args = arguments; |
| 12273 if (retUnwrapped && !this.__chain__) { |
| 12274 return func.apply(this.value(), args); |
| 12275 } |
| 12276 return this[chainName](function(value) { |
| 12277 return func.apply(value, args); |
| 12278 }); |
| 12279 }; |
| 12280 }); |
| 12281 |
| 12282 // Map minified function names to their real names. |
| 12283 baseForOwn(LazyWrapper.prototype, function(func, methodName) { |
| 12284 var lodashFunc = lodash[methodName]; |
| 12285 if (lodashFunc) { |
| 12286 var key = (lodashFunc.name + ''), |
| 12287 names = realNames[key] || (realNames[key] = []); |
| 12288 |
| 12289 names.push({ 'name': methodName, 'func': lodashFunc }); |
| 12290 } |
| 12291 }); |
| 12292 |
| 12293 realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': '
wrapper', 'func': undefined }]; |
| 12294 |
| 12295 // Add functions to the lazy wrapper. |
| 12296 LazyWrapper.prototype.clone = lazyClone; |
| 12297 LazyWrapper.prototype.reverse = lazyReverse; |
| 12298 LazyWrapper.prototype.value = lazyValue; |
| 12299 |
| 12300 // Add chaining functions to the `lodash` wrapper. |
| 12301 lodash.prototype.chain = wrapperChain; |
| 12302 lodash.prototype.commit = wrapperCommit; |
| 12303 lodash.prototype.concat = wrapperConcat; |
| 12304 lodash.prototype.plant = wrapperPlant; |
| 12305 lodash.prototype.reverse = wrapperReverse; |
| 12306 lodash.prototype.toString = wrapperToString; |
| 12307 lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf =
lodash.prototype.value = wrapperValue; |
| 12308 |
| 12309 // Add function aliases to the `lodash` wrapper. |
| 12310 lodash.prototype.collect = lodash.prototype.map; |
| 12311 lodash.prototype.head = lodash.prototype.first; |
| 12312 lodash.prototype.select = lodash.prototype.filter; |
| 12313 lodash.prototype.tail = lodash.prototype.rest; |
| 12314 |
| 12315 return lodash; |
| 12316 } |
| 12317 |
| 12318 /*--------------------------------------------------------------------------*/ |
| 12319 |
| 12320 // Export lodash. |
| 12321 var _ = runInContext(); |
| 12322 |
| 12323 // Some AMD build optimizers like r.js check for condition patterns like the f
ollowing: |
| 12324 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd
) { |
| 12325 // Expose lodash to the global object when an AMD loader is present to avoid |
| 12326 // errors in cases where lodash is loaded by a script tag and not intended |
| 12327 // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for |
| 12328 // more details. |
| 12329 root._ = _; |
| 12330 |
| 12331 // Define as an anonymous module so, through path mapping, it can be |
| 12332 // referenced as the "underscore" module. |
| 12333 define(function() { |
| 12334 return _; |
| 12335 }); |
| 12336 } |
| 12337 // Check for `exports` after `define` in case a build optimizer adds an `expor
ts` object. |
| 12338 else if (freeExports && freeModule) { |
| 12339 // Export for Node.js or RingoJS. |
| 12340 if (moduleExports) { |
| 12341 (freeModule.exports = _)._ = _; |
| 12342 } |
| 12343 // Export for Rhino with CommonJS support. |
| 12344 else { |
| 12345 freeExports._ = _; |
| 12346 } |
| 12347 } |
| 12348 else { |
| 12349 // Export for a browser or Rhino. |
| 12350 root._ = _; |
| 12351 } |
| 12352 }.call(this)); |
| OLD | NEW |