index.js
1 /** 2 * lodash (Custom Build) <https://lodash.com/> 3 * Build: `lodash modularize exports="npm" -o ./` 4 * Copyright jQuery Foundation and other contributors <https://jquery.org/> 5 * Released under MIT license <https://lodash.com/license> 6 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> 7 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 8 */ 9 10 /** Used as the size to enable large array optimizations. */ 11 var LARGE_ARRAY_SIZE = 200; 12 13 /** Used to stand-in for `undefined` hash values. */ 14 var HASH_UNDEFINED = '__lodash_hash_undefined__'; 15 16 /** Used as references for various `Number` constants. */ 17 var MAX_SAFE_INTEGER = 9007199254740991; 18 19 /** `Object#toString` result references. */ 20 var argsTag = '[object Arguments]', 21 funcTag = '[object Function]', 22 genTag = '[object GeneratorFunction]'; 23 24 /** 25 * Used to match `RegExp` 26 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). 27 */ 28 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; 29 30 /** Used to detect host constructors (Safari). */ 31 var reIsHostCtor = /^\[object .+?Constructor\]$/; 32 33 /** Detect free variable `global` from Node.js. */ 34 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; 35 36 /** Detect free variable `self`. */ 37 var freeSelf = typeof self == 'object' && self && self.Object === Object && self; 38 39 /** Used as a reference to the global object. */ 40 var root = freeGlobal || freeSelf || Function('return this')(); 41 42 /** 43 * A faster alternative to `Function#apply`, this function invokes `func` 44 * with the `this` binding of `thisArg` and the arguments of `args`. 45 * 46 * @private 47 * @param {Function} func The function to invoke. 48 * @param {*} thisArg The `this` binding of `func`. 49 * @param {Array} args The arguments to invoke `func` with. 50 * @returns {*} Returns the result of `func`. 51 */ 52 function apply(func, thisArg, args) { 53 switch (args.length) { 54 case 0: return func.call(thisArg); 55 case 1: return func.call(thisArg, args[0]); 56 case 2: return func.call(thisArg, args[0], args[1]); 57 case 3: return func.call(thisArg, args[0], args[1], args[2]); 58 } 59 return func.apply(thisArg, args); 60 } 61 62 /** 63 * A specialized version of `_.includes` for arrays without support for 64 * specifying an index to search from. 65 * 66 * @private 67 * @param {Array} [array] The array to inspect. 68 * @param {*} target The value to search for. 69 * @returns {boolean} Returns `true` if `target` is found, else `false`. 70 */ 71 function arrayIncludes(array, value) { 72 var length = array ? array.length : 0; 73 return !!length && baseIndexOf(array, value, 0) > -1; 74 } 75 76 /** 77 * This function is like `arrayIncludes` except that it accepts a comparator. 78 * 79 * @private 80 * @param {Array} [array] The array to inspect. 81 * @param {*} target The value to search for. 82 * @param {Function} comparator The comparator invoked per element. 83 * @returns {boolean} Returns `true` if `target` is found, else `false`. 84 */ 85 function arrayIncludesWith(array, value, comparator) { 86 var index = -1, 87 length = array ? array.length : 0; 88 89 while (++index < length) { 90 if (comparator(value, array[index])) { 91 return true; 92 } 93 } 94 return false; 95 } 96 97 /** 98 * A specialized version of `_.map` for arrays without support for iteratee 99 * shorthands. 100 * 101 * @private 102 * @param {Array} [array] The array to iterate over. 103 * @param {Function} iteratee The function invoked per iteration. 104 * @returns {Array} Returns the new mapped array. 105 */ 106 function arrayMap(array, iteratee) { 107 var index = -1, 108 length = array ? array.length : 0, 109 result = Array(length); 110 111 while (++index < length) { 112 result[index] = iteratee(array[index], index, array); 113 } 114 return result; 115 } 116 117 /** 118 * Appends the elements of `values` to `array`. 119 * 120 * @private 121 * @param {Array} array The array to modify. 122 * @param {Array} values The values to append. 123 * @returns {Array} Returns `array`. 124 */ 125 function arrayPush(array, values) { 126 var index = -1, 127 length = values.length, 128 offset = array.length; 129 130 while (++index < length) { 131 array[offset + index] = values[index]; 132 } 133 return array; 134 } 135 136 /** 137 * The base implementation of `_.findIndex` and `_.findLastIndex` without 138 * support for iteratee shorthands. 139 * 140 * @private 141 * @param {Array} array The array to inspect. 142 * @param {Function} predicate The function invoked per iteration. 143 * @param {number} fromIndex The index to search from. 144 * @param {boolean} [fromRight] Specify iterating from right to left. 145 * @returns {number} Returns the index of the matched value, else `-1`. 146 */ 147 function baseFindIndex(array, predicate, fromIndex, fromRight) { 148 var length = array.length, 149 index = fromIndex + (fromRight ? 1 : -1); 150 151 while ((fromRight ? index-- : ++index < length)) { 152 if (predicate(array[index], index, array)) { 153 return index; 154 } 155 } 156 return -1; 157 } 158 159 /** 160 * The base implementation of `_.indexOf` without `fromIndex` bounds checks. 161 * 162 * @private 163 * @param {Array} array The array to inspect. 164 * @param {*} value The value to search for. 165 * @param {number} fromIndex The index to search from. 166 * @returns {number} Returns the index of the matched value, else `-1`. 167 */ 168 function baseIndexOf(array, value, fromIndex) { 169 if (value !== value) { 170 return baseFindIndex(array, baseIsNaN, fromIndex); 171 } 172 var index = fromIndex - 1, 173 length = array.length; 174 175 while (++index < length) { 176 if (array[index] === value) { 177 return index; 178 } 179 } 180 return -1; 181 } 182 183 /** 184 * The base implementation of `_.isNaN` without support for number objects. 185 * 186 * @private 187 * @param {*} value The value to check. 188 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. 189 */ 190 function baseIsNaN(value) { 191 return value !== value; 192 } 193 194 /** 195 * The base implementation of `_.unary` without support for storing metadata. 196 * 197 * @private 198 * @param {Function} func The function to cap arguments for. 199 * @returns {Function} Returns the new capped function. 200 */ 201 function baseUnary(func) { 202 return function(value) { 203 return func(value); 204 }; 205 } 206 207 /** 208 * Checks if a cache value for `key` exists. 209 * 210 * @private 211 * @param {Object} cache The cache to query. 212 * @param {string} key The key of the entry to check. 213 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. 214 */ 215 function cacheHas(cache, key) { 216 return cache.has(key); 217 } 218 219 /** 220 * Gets the value at `key` of `object`. 221 * 222 * @private 223 * @param {Object} [object] The object to query. 224 * @param {string} key The key of the property to get. 225 * @returns {*} Returns the property value. 226 */ 227 function getValue(object, key) { 228 return object == null ? undefined : object[key]; 229 } 230 231 /** 232 * Checks if `value` is a host object in IE < 9. 233 * 234 * @private 235 * @param {*} value The value to check. 236 * @returns {boolean} Returns `true` if `value` is a host object, else `false`. 237 */ 238 function isHostObject(value) { 239 // Many host objects are `Object` objects that can coerce to strings 240 // despite having improperly defined `toString` methods. 241 var result = false; 242 if (value != null && typeof value.toString != 'function') { 243 try { 244 result = !!(value + ''); 245 } catch (e) {} 246 } 247 return result; 248 } 249 250 /** Used for built-in method references. */ 251 var arrayProto = Array.prototype, 252 funcProto = Function.prototype, 253 objectProto = Object.prototype; 254 255 /** Used to detect overreaching core-js shims. */ 256 var coreJsData = root['__core-js_shared__']; 257 258 /** Used to detect methods masquerading as native. */ 259 var maskSrcKey = (function() { 260 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); 261 return uid ? ('Symbol(src)_1.' + uid) : ''; 262 }()); 263 264 /** Used to resolve the decompiled source of functions. */ 265 var funcToString = funcProto.toString; 266 267 /** Used to check objects for own properties. */ 268 var hasOwnProperty = objectProto.hasOwnProperty; 269 270 /** 271 * Used to resolve the 272 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 273 * of values. 274 */ 275 var objectToString = objectProto.toString; 276 277 /** Used to detect if a method is native. */ 278 var reIsNative = RegExp('^' + 279 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') 280 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' 281 ); 282 283 /** Built-in value references. */ 284 var Symbol = root.Symbol, 285 propertyIsEnumerable = objectProto.propertyIsEnumerable, 286 splice = arrayProto.splice, 287 spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; 288 289 /* Built-in method references for those with the same name as other `lodash` methods. */ 290 var nativeMax = Math.max; 291 292 /* Built-in method references that are verified to be native. */ 293 var Map = getNative(root, 'Map'), 294 nativeCreate = getNative(Object, 'create'); 295 296 /** 297 * Creates a hash object. 298 * 299 * @private 300 * @constructor 301 * @param {Array} [entries] The key-value pairs to cache. 302 */ 303 function Hash(entries) { 304 var index = -1, 305 length = entries ? entries.length : 0; 306 307 this.clear(); 308 while (++index < length) { 309 var entry = entries[index]; 310 this.set(entry[0], entry[1]); 311 } 312 } 313 314 /** 315 * Removes all key-value entries from the hash. 316 * 317 * @private 318 * @name clear 319 * @memberOf Hash 320 */ 321 function hashClear() { 322 this.__data__ = nativeCreate ? nativeCreate(null) : {}; 323 } 324 325 /** 326 * Removes `key` and its value from the hash. 327 * 328 * @private 329 * @name delete 330 * @memberOf Hash 331 * @param {Object} hash The hash to modify. 332 * @param {string} key The key of the value to remove. 333 * @returns {boolean} Returns `true` if the entry was removed, else `false`. 334 */ 335 function hashDelete(key) { 336 return this.has(key) && delete this.__data__[key]; 337 } 338 339 /** 340 * Gets the hash value for `key`. 341 * 342 * @private 343 * @name get 344 * @memberOf Hash 345 * @param {string} key The key of the value to get. 346 * @returns {*} Returns the entry value. 347 */ 348 function hashGet(key) { 349 var data = this.__data__; 350 if (nativeCreate) { 351 var result = data[key]; 352 return result === HASH_UNDEFINED ? undefined : result; 353 } 354 return hasOwnProperty.call(data, key) ? data[key] : undefined; 355 } 356 357 /** 358 * Checks if a hash value for `key` exists. 359 * 360 * @private 361 * @name has 362 * @memberOf Hash 363 * @param {string} key The key of the entry to check. 364 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. 365 */ 366 function hashHas(key) { 367 var data = this.__data__; 368 return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); 369 } 370 371 /** 372 * Sets the hash `key` to `value`. 373 * 374 * @private 375 * @name set 376 * @memberOf Hash 377 * @param {string} key The key of the value to set. 378 * @param {*} value The value to set. 379 * @returns {Object} Returns the hash instance. 380 */ 381 function hashSet(key, value) { 382 var data = this.__data__; 383 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; 384 return this; 385 } 386 387 // Add methods to `Hash`. 388 Hash.prototype.clear = hashClear; 389 Hash.prototype['delete'] = hashDelete; 390 Hash.prototype.get = hashGet; 391 Hash.prototype.has = hashHas; 392 Hash.prototype.set = hashSet; 393 394 /** 395 * Creates an list cache object. 396 * 397 * @private 398 * @constructor 399 * @param {Array} [entries] The key-value pairs to cache. 400 */ 401 function ListCache(entries) { 402 var index = -1, 403 length = entries ? entries.length : 0; 404 405 this.clear(); 406 while (++index < length) { 407 var entry = entries[index]; 408 this.set(entry[0], entry[1]); 409 } 410 } 411 412 /** 413 * Removes all key-value entries from the list cache. 414 * 415 * @private 416 * @name clear 417 * @memberOf ListCache 418 */ 419 function listCacheClear() { 420 this.__data__ = []; 421 } 422 423 /** 424 * Removes `key` and its value from the list cache. 425 * 426 * @private 427 * @name delete 428 * @memberOf ListCache 429 * @param {string} key The key of the value to remove. 430 * @returns {boolean} Returns `true` if the entry was removed, else `false`. 431 */ 432 function listCacheDelete(key) { 433 var data = this.__data__, 434 index = assocIndexOf(data, key); 435 436 if (index < 0) { 437 return false; 438 } 439 var lastIndex = data.length - 1; 440 if (index == lastIndex) { 441 data.pop(); 442 } else { 443 splice.call(data, index, 1); 444 } 445 return true; 446 } 447 448 /** 449 * Gets the list cache value for `key`. 450 * 451 * @private 452 * @name get 453 * @memberOf ListCache 454 * @param {string} key The key of the value to get. 455 * @returns {*} Returns the entry value. 456 */ 457 function listCacheGet(key) { 458 var data = this.__data__, 459 index = assocIndexOf(data, key); 460 461 return index < 0 ? undefined : data[index][1]; 462 } 463 464 /** 465 * Checks if a list cache value for `key` exists. 466 * 467 * @private 468 * @name has 469 * @memberOf ListCache 470 * @param {string} key The key of the entry to check. 471 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. 472 */ 473 function listCacheHas(key) { 474 return assocIndexOf(this.__data__, key) > -1; 475 } 476 477 /** 478 * Sets the list cache `key` to `value`. 479 * 480 * @private 481 * @name set 482 * @memberOf ListCache 483 * @param {string} key The key of the value to set. 484 * @param {*} value The value to set. 485 * @returns {Object} Returns the list cache instance. 486 */ 487 function listCacheSet(key, value) { 488 var data = this.__data__, 489 index = assocIndexOf(data, key); 490 491 if (index < 0) { 492 data.push([key, value]); 493 } else { 494 data[index][1] = value; 495 } 496 return this; 497 } 498 499 // Add methods to `ListCache`. 500 ListCache.prototype.clear = listCacheClear; 501 ListCache.prototype['delete'] = listCacheDelete; 502 ListCache.prototype.get = listCacheGet; 503 ListCache.prototype.has = listCacheHas; 504 ListCache.prototype.set = listCacheSet; 505 506 /** 507 * Creates a map cache object to store key-value pairs. 508 * 509 * @private 510 * @constructor 511 * @param {Array} [entries] The key-value pairs to cache. 512 */ 513 function MapCache(entries) { 514 var index = -1, 515 length = entries ? entries.length : 0; 516 517 this.clear(); 518 while (++index < length) { 519 var entry = entries[index]; 520 this.set(entry[0], entry[1]); 521 } 522 } 523 524 /** 525 * Removes all key-value entries from the map. 526 * 527 * @private 528 * @name clear 529 * @memberOf MapCache 530 */ 531 function mapCacheClear() { 532 this.__data__ = { 533 'hash': new Hash, 534 'map': new (Map || ListCache), 535 'string': new Hash 536 }; 537 } 538 539 /** 540 * Removes `key` and its value from the map. 541 * 542 * @private 543 * @name delete 544 * @memberOf MapCache 545 * @param {string} key The key of the value to remove. 546 * @returns {boolean} Returns `true` if the entry was removed, else `false`. 547 */ 548 function mapCacheDelete(key) { 549 return getMapData(this, key)['delete'](key); 550 } 551 552 /** 553 * Gets the map value for `key`. 554 * 555 * @private 556 * @name get 557 * @memberOf MapCache 558 * @param {string} key The key of the value to get. 559 * @returns {*} Returns the entry value. 560 */ 561 function mapCacheGet(key) { 562 return getMapData(this, key).get(key); 563 } 564 565 /** 566 * Checks if a map value for `key` exists. 567 * 568 * @private 569 * @name has 570 * @memberOf MapCache 571 * @param {string} key The key of the entry to check. 572 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. 573 */ 574 function mapCacheHas(key) { 575 return getMapData(this, key).has(key); 576 } 577 578 /** 579 * Sets the map `key` to `value`. 580 * 581 * @private 582 * @name set 583 * @memberOf MapCache 584 * @param {string} key The key of the value to set. 585 * @param {*} value The value to set. 586 * @returns {Object} Returns the map cache instance. 587 */ 588 function mapCacheSet(key, value) { 589 getMapData(this, key).set(key, value); 590 return this; 591 } 592 593 // Add methods to `MapCache`. 594 MapCache.prototype.clear = mapCacheClear; 595 MapCache.prototype['delete'] = mapCacheDelete; 596 MapCache.prototype.get = mapCacheGet; 597 MapCache.prototype.has = mapCacheHas; 598 MapCache.prototype.set = mapCacheSet; 599 600 /** 601 * 602 * Creates an array cache object to store unique values. 603 * 604 * @private 605 * @constructor 606 * @param {Array} [values] The values to cache. 607 */ 608 function SetCache(values) { 609 var index = -1, 610 length = values ? values.length : 0; 611 612 this.__data__ = new MapCache; 613 while (++index < length) { 614 this.add(values[index]); 615 } 616 } 617 618 /** 619 * Adds `value` to the array cache. 620 * 621 * @private 622 * @name add 623 * @memberOf SetCache 624 * @alias push 625 * @param {*} value The value to cache. 626 * @returns {Object} Returns the cache instance. 627 */ 628 function setCacheAdd(value) { 629 this.__data__.set(value, HASH_UNDEFINED); 630 return this; 631 } 632 633 /** 634 * Checks if `value` is in the array cache. 635 * 636 * @private 637 * @name has 638 * @memberOf SetCache 639 * @param {*} value The value to search for. 640 * @returns {number} Returns `true` if `value` is found, else `false`. 641 */ 642 function setCacheHas(value) { 643 return this.__data__.has(value); 644 } 645 646 // Add methods to `SetCache`. 647 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; 648 SetCache.prototype.has = setCacheHas; 649 650 /** 651 * Gets the index at which the `key` is found in `array` of key-value pairs. 652 * 653 * @private 654 * @param {Array} array The array to inspect. 655 * @param {*} key The key to search for. 656 * @returns {number} Returns the index of the matched value, else `-1`. 657 */ 658 function assocIndexOf(array, key) { 659 var length = array.length; 660 while (length--) { 661 if (eq(array[length][0], key)) { 662 return length; 663 } 664 } 665 return -1; 666 } 667 668 /** 669 * The base implementation of methods like `_.difference` without support 670 * for excluding multiple arrays or iteratee shorthands. 671 * 672 * @private 673 * @param {Array} array The array to inspect. 674 * @param {Array} values The values to exclude. 675 * @param {Function} [iteratee] The iteratee invoked per element. 676 * @param {Function} [comparator] The comparator invoked per element. 677 * @returns {Array} Returns the new array of filtered values. 678 */ 679 function baseDifference(array, values, iteratee, comparator) { 680 var index = -1, 681 includes = arrayIncludes, 682 isCommon = true, 683 length = array.length, 684 result = [], 685 valuesLength = values.length; 686 687 if (!length) { 688 return result; 689 } 690 if (iteratee) { 691 values = arrayMap(values, baseUnary(iteratee)); 692 } 693 if (comparator) { 694 includes = arrayIncludesWith; 695 isCommon = false; 696 } 697 else if (values.length >= LARGE_ARRAY_SIZE) { 698 includes = cacheHas; 699 isCommon = false; 700 values = new SetCache(values); 701 } 702 outer: 703 while (++index < length) { 704 var value = array[index], 705 computed = iteratee ? iteratee(value) : value; 706 707 value = (comparator || value !== 0) ? value : 0; 708 if (isCommon && computed === computed) { 709 var valuesIndex = valuesLength; 710 while (valuesIndex--) { 711 if (values[valuesIndex] === computed) { 712 continue outer; 713 } 714 } 715 result.push(value); 716 } 717 else if (!includes(values, computed, comparator)) { 718 result.push(value); 719 } 720 } 721 return result; 722 } 723 724 /** 725 * The base implementation of `_.flatten` with support for restricting flattening. 726 * 727 * @private 728 * @param {Array} array The array to flatten. 729 * @param {number} depth The maximum recursion depth. 730 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. 731 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. 732 * @param {Array} [result=[]] The initial result value. 733 * @returns {Array} Returns the new flattened array. 734 */ 735 function baseFlatten(array, depth, predicate, isStrict, result) { 736 var index = -1, 737 length = array.length; 738 739 predicate || (predicate = isFlattenable); 740 result || (result = []); 741 742 while (++index < length) { 743 var value = array[index]; 744 if (depth > 0 && predicate(value)) { 745 if (depth > 1) { 746 // Recursively flatten arrays (susceptible to call stack limits). 747 baseFlatten(value, depth - 1, predicate, isStrict, result); 748 } else { 749 arrayPush(result, value); 750 } 751 } else if (!isStrict) { 752 result[result.length] = value; 753 } 754 } 755 return result; 756 } 757 758 /** 759 * The base implementation of `_.isNative` without bad shim checks. 760 * 761 * @private 762 * @param {*} value The value to check. 763 * @returns {boolean} Returns `true` if `value` is a native function, 764 * else `false`. 765 */ 766 function baseIsNative(value) { 767 if (!isObject(value) || isMasked(value)) { 768 return false; 769 } 770 var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; 771 return pattern.test(toSource(value)); 772 } 773 774 /** 775 * The base implementation of `_.rest` which doesn't validate or coerce arguments. 776 * 777 * @private 778 * @param {Function} func The function to apply a rest parameter to. 779 * @param {number} [start=func.length-1] The start position of the rest parameter. 780 * @returns {Function} Returns the new function. 781 */ 782 function baseRest(func, start) { 783 start = nativeMax(start === undefined ? (func.length - 1) : start, 0); 784 return function() { 785 var args = arguments, 786 index = -1, 787 length = nativeMax(args.length - start, 0), 788 array = Array(length); 789 790 while (++index < length) { 791 array[index] = args[start + index]; 792 } 793 index = -1; 794 var otherArgs = Array(start + 1); 795 while (++index < start) { 796 otherArgs[index] = args[index]; 797 } 798 otherArgs[start] = array; 799 return apply(func, this, otherArgs); 800 }; 801 } 802 803 /** 804 * Gets the data for `map`. 805 * 806 * @private 807 * @param {Object} map The map to query. 808 * @param {string} key The reference key. 809 * @returns {*} Returns the map data. 810 */ 811 function getMapData(map, key) { 812 var data = map.__data__; 813 return isKeyable(key) 814 ? data[typeof key == 'string' ? 'string' : 'hash'] 815 : data.map; 816 } 817 818 /** 819 * Gets the native function at `key` of `object`. 820 * 821 * @private 822 * @param {Object} object The object to query. 823 * @param {string} key The key of the method to get. 824 * @returns {*} Returns the function if it's native, else `undefined`. 825 */ 826 function getNative(object, key) { 827 var value = getValue(object, key); 828 return baseIsNative(value) ? value : undefined; 829 } 830 831 /** 832 * Checks if `value` is a flattenable `arguments` object or array. 833 * 834 * @private 835 * @param {*} value The value to check. 836 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. 837 */ 838 function isFlattenable(value) { 839 return isArray(value) || isArguments(value) || 840 !!(spreadableSymbol && value && value[spreadableSymbol]); 841 } 842 843 /** 844 * Checks if `value` is suitable for use as unique object key. 845 * 846 * @private 847 * @param {*} value The value to check. 848 * @returns {boolean} Returns `true` if `value` is suitable, else `false`. 849 */ 850 function isKeyable(value) { 851 var type = typeof value; 852 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') 853 ? (value !== '__proto__') 854 : (value === null); 855 } 856 857 /** 858 * Checks if `func` has its source masked. 859 * 860 * @private 861 * @param {Function} func The function to check. 862 * @returns {boolean} Returns `true` if `func` is masked, else `false`. 863 */ 864 function isMasked(func) { 865 return !!maskSrcKey && (maskSrcKey in func); 866 } 867 868 /** 869 * Converts `func` to its source code. 870 * 871 * @private 872 * @param {Function} func The function to process. 873 * @returns {string} Returns the source code. 874 */ 875 function toSource(func) { 876 if (func != null) { 877 try { 878 return funcToString.call(func); 879 } catch (e) {} 880 try { 881 return (func + ''); 882 } catch (e) {} 883 } 884 return ''; 885 } 886 887 /** 888 * Creates an array of `array` values not included in the other given arrays 889 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) 890 * for equality comparisons. The order of result values is determined by the 891 * order they occur in the first array. 892 * 893 * **Note:** Unlike `_.pullAll`, this method returns a new array. 894 * 895 * @static 896 * @memberOf _ 897 * @since 0.1.0 898 * @category Array 899 * @param {Array} array The array to inspect. 900 * @param {...Array} [values] The values to exclude. 901 * @returns {Array} Returns the new array of filtered values. 902 * @see _.without, _.xor 903 * @example 904 * 905 * _.difference([2, 1], [2, 3]); 906 * // => [1] 907 */ 908 var difference = baseRest(function(array, values) { 909 return isArrayLikeObject(array) 910 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) 911 : []; 912 }); 913 914 /** 915 * Performs a 916 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) 917 * comparison between two values to determine if they are equivalent. 918 * 919 * @static 920 * @memberOf _ 921 * @since 4.0.0 922 * @category Lang 923 * @param {*} value The value to compare. 924 * @param {*} other The other value to compare. 925 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. 926 * @example 927 * 928 * var object = { 'a': 1 }; 929 * var other = { 'a': 1 }; 930 * 931 * _.eq(object, object); 932 * // => true 933 * 934 * _.eq(object, other); 935 * // => false 936 * 937 * _.eq('a', 'a'); 938 * // => true 939 * 940 * _.eq('a', Object('a')); 941 * // => false 942 * 943 * _.eq(NaN, NaN); 944 * // => true 945 */ 946 function eq(value, other) { 947 return value === other || (value !== value && other !== other); 948 } 949 950 /** 951 * Checks if `value` is likely an `arguments` object. 952 * 953 * @static 954 * @memberOf _ 955 * @since 0.1.0 956 * @category Lang 957 * @param {*} value The value to check. 958 * @returns {boolean} Returns `true` if `value` is an `arguments` object, 959 * else `false`. 960 * @example 961 * 962 * _.isArguments(function() { return arguments; }()); 963 * // => true 964 * 965 * _.isArguments([1, 2, 3]); 966 * // => false 967 */ 968 function isArguments(value) { 969 // Safari 8.1 makes `arguments.callee` enumerable in strict mode. 970 return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && 971 (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); 972 } 973 974 /** 975 * Checks if `value` is classified as an `Array` object. 976 * 977 * @static 978 * @memberOf _ 979 * @since 0.1.0 980 * @category Lang 981 * @param {*} value The value to check. 982 * @returns {boolean} Returns `true` if `value` is an array, else `false`. 983 * @example 984 * 985 * _.isArray([1, 2, 3]); 986 * // => true 987 * 988 * _.isArray(document.body.children); 989 * // => false 990 * 991 * _.isArray('abc'); 992 * // => false 993 * 994 * _.isArray(_.noop); 995 * // => false 996 */ 997 var isArray = Array.isArray; 998 999 /** 1000 * Checks if `value` is array-like. A value is considered array-like if it's 1001 * not a function and has a `value.length` that's an integer greater than or 1002 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. 1003 * 1004 * @static 1005 * @memberOf _ 1006 * @since 4.0.0 1007 * @category Lang 1008 * @param {*} value The value to check. 1009 * @returns {boolean} Returns `true` if `value` is array-like, else `false`. 1010 * @example 1011 * 1012 * _.isArrayLike([1, 2, 3]); 1013 * // => true 1014 * 1015 * _.isArrayLike(document.body.children); 1016 * // => true 1017 * 1018 * _.isArrayLike('abc'); 1019 * // => true 1020 * 1021 * _.isArrayLike(_.noop); 1022 * // => false 1023 */ 1024 function isArrayLike(value) { 1025 return value != null && isLength(value.length) && !isFunction(value); 1026 } 1027 1028 /** 1029 * This method is like `_.isArrayLike` except that it also checks if `value` 1030 * is an object. 1031 * 1032 * @static 1033 * @memberOf _ 1034 * @since 4.0.0 1035 * @category Lang 1036 * @param {*} value The value to check. 1037 * @returns {boolean} Returns `true` if `value` is an array-like object, 1038 * else `false`. 1039 * @example 1040 * 1041 * _.isArrayLikeObject([1, 2, 3]); 1042 * // => true 1043 * 1044 * _.isArrayLikeObject(document.body.children); 1045 * // => true 1046 * 1047 * _.isArrayLikeObject('abc'); 1048 * // => false 1049 * 1050 * _.isArrayLikeObject(_.noop); 1051 * // => false 1052 */ 1053 function isArrayLikeObject(value) { 1054 return isObjectLike(value) && isArrayLike(value); 1055 } 1056 1057 /** 1058 * Checks if `value` is classified as a `Function` object. 1059 * 1060 * @static 1061 * @memberOf _ 1062 * @since 0.1.0 1063 * @category Lang 1064 * @param {*} value The value to check. 1065 * @returns {boolean} Returns `true` if `value` is a function, else `false`. 1066 * @example 1067 * 1068 * _.isFunction(_); 1069 * // => true 1070 * 1071 * _.isFunction(/abc/); 1072 * // => false 1073 */ 1074 function isFunction(value) { 1075 // The use of `Object#toString` avoids issues with the `typeof` operator 1076 // in Safari 8-9 which returns 'object' for typed array and other constructors. 1077 var tag = isObject(value) ? objectToString.call(value) : ''; 1078 return tag == funcTag || tag == genTag; 1079 } 1080 1081 /** 1082 * Checks if `value` is a valid array-like length. 1083 * 1084 * **Note:** This method is loosely based on 1085 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). 1086 * 1087 * @static 1088 * @memberOf _ 1089 * @since 4.0.0 1090 * @category Lang 1091 * @param {*} value The value to check. 1092 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. 1093 * @example 1094 * 1095 * _.isLength(3); 1096 * // => true 1097 * 1098 * _.isLength(Number.MIN_VALUE); 1099 * // => false 1100 * 1101 * _.isLength(Infinity); 1102 * // => false 1103 * 1104 * _.isLength('3'); 1105 * // => false 1106 */ 1107 function isLength(value) { 1108 return typeof value == 'number' && 1109 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; 1110 } 1111 1112 /** 1113 * Checks if `value` is the 1114 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) 1115 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) 1116 * 1117 * @static 1118 * @memberOf _ 1119 * @since 0.1.0 1120 * @category Lang 1121 * @param {*} value The value to check. 1122 * @returns {boolean} Returns `true` if `value` is an object, else `false`. 1123 * @example 1124 * 1125 * _.isObject({}); 1126 * // => true 1127 * 1128 * _.isObject([1, 2, 3]); 1129 * // => true 1130 * 1131 * _.isObject(_.noop); 1132 * // => true 1133 * 1134 * _.isObject(null); 1135 * // => false 1136 */ 1137 function isObject(value) { 1138 var type = typeof value; 1139 return !!value && (type == 'object' || type == 'function'); 1140 } 1141 1142 /** 1143 * Checks if `value` is object-like. A value is object-like if it's not `null` 1144 * and has a `typeof` result of "object". 1145 * 1146 * @static 1147 * @memberOf _ 1148 * @since 4.0.0 1149 * @category Lang 1150 * @param {*} value The value to check. 1151 * @returns {boolean} Returns `true` if `value` is object-like, else `false`. 1152 * @example 1153 * 1154 * _.isObjectLike({}); 1155 * // => true 1156 * 1157 * _.isObjectLike([1, 2, 3]); 1158 * // => true 1159 * 1160 * _.isObjectLike(_.noop); 1161 * // => false 1162 * 1163 * _.isObjectLike(null); 1164 * // => false 1165 */ 1166 function isObjectLike(value) { 1167 return !!value && typeof value == 'object'; 1168 } 1169 1170 module.exports = difference;