mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-04 00:57:48 +00:00
wip: migrate to bun
This commit is contained in:
18
src/.eslintrc.cjs
Normal file
18
src/.eslintrc.cjs
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('node:path');
|
||||
|
||||
module.exports = {
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.{ts}'],
|
||||
rules: {
|
||||
'import/no-extraneous-dependencies': [
|
||||
'error',
|
||||
// Use package.json from both this package folder and root.
|
||||
{ packageDir: [__dirname, path.join(__dirname, '../')] },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
88
src/.internal/Hash.ts
Normal file
88
src/.internal/Hash.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
/** Used to stand-in for `undefined` hash values. */
|
||||
const HASH_UNDEFINED = '__lodash_hash_undefined__'
|
||||
|
||||
class Hash {
|
||||
|
||||
/**
|
||||
* Creates a hash object.
|
||||
*
|
||||
* @private
|
||||
* @constructor
|
||||
* @param {Array} [entries] The key-value pairs to cache.
|
||||
*/
|
||||
constructor(entries) {
|
||||
let index = -1
|
||||
const length = entries == null ? 0 : entries.length
|
||||
|
||||
this.clear()
|
||||
while (++index < length) {
|
||||
const entry = entries[index]
|
||||
this.set(entry[0], entry[1])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value entries from the hash.
|
||||
*
|
||||
* @memberOf Hash
|
||||
*/
|
||||
clear() {
|
||||
this.__data__ = Object.create(null)
|
||||
this.size = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes `key` and its value from the hash.
|
||||
*
|
||||
* @memberOf Hash
|
||||
* @param {string} key The key of the value to remove.
|
||||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||||
*/
|
||||
delete(key) {
|
||||
const result = this.has(key) && delete this.__data__[key]
|
||||
this.size -= result ? 1 : 0
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hash value for `key`.
|
||||
*
|
||||
* @memberOf Hash
|
||||
* @param {string} key The key of the value to get.
|
||||
* @returns {*} Returns the entry value.
|
||||
*/
|
||||
get(key) {
|
||||
const data = this.__data__
|
||||
const result = data[key]
|
||||
return result === HASH_UNDEFINED ? undefined : result
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a hash value for `key` exists.
|
||||
*
|
||||
* @memberOf Hash
|
||||
* @param {string} key The key of the entry to check.
|
||||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||||
*/
|
||||
has(key) {
|
||||
const data = this.__data__
|
||||
return data[key] !== undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hash `key` to `value`.
|
||||
*
|
||||
* @memberOf Hash
|
||||
* @param {string} key The key of the value to set.
|
||||
* @param {*} value The value to set.
|
||||
* @returns {Object} Returns the hash instance.
|
||||
*/
|
||||
set(key, value) {
|
||||
const data = this.__data__
|
||||
this.size += this.has(key) ? 0 : 1
|
||||
data[key] = value === undefined ? HASH_UNDEFINED : value
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
export default Hash
|
||||
103
src/.internal/ListCache.ts
Normal file
103
src/.internal/ListCache.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import assocIndexOf from './assocIndexOf.js'
|
||||
|
||||
class ListCache {
|
||||
|
||||
/**
|
||||
* Creates an list cache object.
|
||||
*
|
||||
* @private
|
||||
* @constructor
|
||||
* @param {Array} [entries] The key-value pairs to cache.
|
||||
*/
|
||||
constructor(entries) {
|
||||
let index = -1
|
||||
const length = entries == null ? 0 : entries.length
|
||||
|
||||
this.clear()
|
||||
while (++index < length) {
|
||||
const entry = entries[index]
|
||||
this.set(entry[0], entry[1])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value entries from the list cache.
|
||||
*
|
||||
* @memberOf ListCache
|
||||
*/
|
||||
clear() {
|
||||
this.__data__ = []
|
||||
this.size = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes `key` and its value from the list cache.
|
||||
*
|
||||
* @memberOf ListCache
|
||||
* @param {string} key The key of the value to remove.
|
||||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||||
*/
|
||||
delete(key) {
|
||||
const data = this.__data__
|
||||
const index = assocIndexOf(data, key)
|
||||
|
||||
if (index < 0) {
|
||||
return false
|
||||
}
|
||||
const lastIndex = data.length - 1
|
||||
if (index == lastIndex) {
|
||||
data.pop()
|
||||
} else {
|
||||
data.splice(index, 1)
|
||||
}
|
||||
--this.size
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list cache value for `key`.
|
||||
*
|
||||
* @memberOf ListCache
|
||||
* @param {string} key The key of the value to get.
|
||||
* @returns {*} Returns the entry value.
|
||||
*/
|
||||
get(key) {
|
||||
const data = this.__data__
|
||||
const index = assocIndexOf(data, key)
|
||||
return index < 0 ? undefined : data[index][1]
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a list cache value for `key` exists.
|
||||
*
|
||||
* @memberOf ListCache
|
||||
* @param {string} key The key of the entry to check.
|
||||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||||
*/
|
||||
has(key) {
|
||||
return assocIndexOf(this.__data__, key) > -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list cache `key` to `value`.
|
||||
*
|
||||
* @memberOf ListCache
|
||||
* @param {string} key The key of the value to set.
|
||||
* @param {*} value The value to set.
|
||||
* @returns {Object} Returns the list cache instance.
|
||||
*/
|
||||
set(key, value) {
|
||||
const data = this.__data__
|
||||
const index = assocIndexOf(data, key)
|
||||
|
||||
if (index < 0) {
|
||||
++this.size
|
||||
data.push([key, value])
|
||||
} else {
|
||||
data[index][1] = value
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
export default ListCache
|
||||
120
src/.internal/MapCache.ts
Normal file
120
src/.internal/MapCache.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
import Hash from './Hash.js'
|
||||
|
||||
/**
|
||||
* Gets the data for `map`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} map The map to query.
|
||||
* @param {string} key The reference key.
|
||||
* @returns {*} Returns the map data.
|
||||
*/
|
||||
function getMapData({ __data__ }, key) {
|
||||
const data = __data__
|
||||
return isKeyable(key)
|
||||
? data[typeof key === 'string' ? 'string' : 'hash']
|
||||
: data.map
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if `value` is suitable for use as unique object key.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
||||
*/
|
||||
function isKeyable(value) {
|
||||
const type = typeof value
|
||||
return (type === 'string' || type === 'number' || type === 'symbol' || type === 'boolean')
|
||||
? (value !== '__proto__')
|
||||
: (value === null)
|
||||
}
|
||||
|
||||
class MapCache {
|
||||
|
||||
/**
|
||||
* Creates a map cache object to store key-value pairs.
|
||||
*
|
||||
* @private
|
||||
* @constructor
|
||||
* @param {Array} [entries] The key-value pairs to cache.
|
||||
*/
|
||||
constructor(entries) {
|
||||
let index = -1
|
||||
const length = entries == null ? 0 : entries.length
|
||||
|
||||
this.clear()
|
||||
while (++index < length) {
|
||||
const entry = entries[index]
|
||||
this.set(entry[0], entry[1])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value entries from the map.
|
||||
*
|
||||
* @memberOf MapCache
|
||||
*/
|
||||
clear() {
|
||||
this.size = 0
|
||||
this.__data__ = {
|
||||
'hash': new Hash,
|
||||
'map': new Map,
|
||||
'string': new Hash
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes `key` and its value from the map.
|
||||
*
|
||||
* @memberOf MapCache
|
||||
* @param {string} key The key of the value to remove.
|
||||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||||
*/
|
||||
delete(key) {
|
||||
const result = getMapData(this, key)['delete'](key)
|
||||
this.size -= result ? 1 : 0
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map value for `key`.
|
||||
*
|
||||
* @memberOf MapCache
|
||||
* @param {string} key The key of the value to get.
|
||||
* @returns {*} Returns the entry value.
|
||||
*/
|
||||
get(key) {
|
||||
return getMapData(this, key).get(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a map value for `key` exists.
|
||||
*
|
||||
* @memberOf MapCache
|
||||
* @param {string} key The key of the entry to check.
|
||||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||||
*/
|
||||
has(key) {
|
||||
return getMapData(this, key).has(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the map `key` to `value`.
|
||||
*
|
||||
* @memberOf MapCache
|
||||
* @param {string} key The key of the value to set.
|
||||
* @param {*} value The value to set.
|
||||
* @returns {Object} Returns the map cache instance.
|
||||
*/
|
||||
set(key, value) {
|
||||
const data = getMapData(this, key)
|
||||
const size = data.size
|
||||
|
||||
data.set(key, value)
|
||||
this.size += data.size == size ? 0 : 1
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
export default MapCache
|
||||
52
src/.internal/SetCache.ts
Normal file
52
src/.internal/SetCache.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import MapCache from './MapCache.js'
|
||||
|
||||
/** Used to stand-in for `undefined` hash values. */
|
||||
const HASH_UNDEFINED = '__lodash_hash_undefined__'
|
||||
|
||||
class SetCache {
|
||||
|
||||
/**
|
||||
* Creates an array cache object to store unique values.
|
||||
*
|
||||
* @private
|
||||
* @constructor
|
||||
* @param {Array} [values] The values to cache.
|
||||
*/
|
||||
constructor(values) {
|
||||
let index = -1
|
||||
const length = values == null ? 0 : values.length
|
||||
|
||||
this.__data__ = new MapCache
|
||||
while (++index < length) {
|
||||
this.add(values[index])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `value` to the array cache.
|
||||
*
|
||||
* @memberOf SetCache
|
||||
* @alias push
|
||||
* @param {*} value The value to cache.
|
||||
* @returns {Object} Returns the cache instance.
|
||||
*/
|
||||
add(value) {
|
||||
this.__data__.set(value, HASH_UNDEFINED)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if `value` is in the array cache.
|
||||
*
|
||||
* @memberOf SetCache
|
||||
* @param {*} value The value to search for.
|
||||
* @returns {boolean} Returns `true` if `value` is found, else `false`.
|
||||
*/
|
||||
has(value) {
|
||||
return this.__data__.has(value)
|
||||
}
|
||||
}
|
||||
|
||||
SetCache.prototype.push = SetCache.prototype.add
|
||||
|
||||
export default SetCache
|
||||
93
src/.internal/Stack.ts
Normal file
93
src/.internal/Stack.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import ListCache from './ListCache.js'
|
||||
import MapCache from './MapCache.js'
|
||||
|
||||
/** Used as the size to enable large array optimizations. */
|
||||
const LARGE_ARRAY_SIZE = 200
|
||||
|
||||
class Stack {
|
||||
|
||||
/**
|
||||
* Creates a stack cache object to store key-value pairs.
|
||||
*
|
||||
* @private
|
||||
* @constructor
|
||||
* @param {Array} [entries] The key-value pairs to cache.
|
||||
*/
|
||||
constructor(entries) {
|
||||
const data = this.__data__ = new ListCache(entries)
|
||||
this.size = data.size
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value entries from the stack.
|
||||
*
|
||||
* @memberOf Stack
|
||||
*/
|
||||
clear() {
|
||||
this.__data__ = new ListCache
|
||||
this.size = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes `key` and its value from the stack.
|
||||
*
|
||||
* @memberOf Stack
|
||||
* @param {string} key The key of the value to remove.
|
||||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||||
*/
|
||||
delete(key) {
|
||||
const data = this.__data__
|
||||
const result = data['delete'](key)
|
||||
|
||||
this.size = data.size
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stack value for `key`.
|
||||
*
|
||||
* @memberOf Stack
|
||||
* @param {string} key The key of the value to get.
|
||||
* @returns {*} Returns the entry value.
|
||||
*/
|
||||
get(key) {
|
||||
return this.__data__.get(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a stack value for `key` exists.
|
||||
*
|
||||
* @memberOf Stack
|
||||
* @param {string} key The key of the entry to check.
|
||||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||||
*/
|
||||
has(key) {
|
||||
return this.__data__.has(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stack `key` to `value`.
|
||||
*
|
||||
* @memberOf Stack
|
||||
* @param {string} key The key of the value to set.
|
||||
* @param {*} value The value to set.
|
||||
* @returns {Object} Returns the stack cache instance.
|
||||
*/
|
||||
set(key, value) {
|
||||
let data = this.__data__
|
||||
if (data instanceof ListCache) {
|
||||
const pairs = data.__data__
|
||||
if (pairs.length < LARGE_ARRAY_SIZE - 1) {
|
||||
pairs.push([key, value])
|
||||
this.size = ++data.size
|
||||
return this
|
||||
}
|
||||
data = this.__data__ = new MapCache(pairs)
|
||||
}
|
||||
data.set(key, value)
|
||||
this.size = data.size
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
export default Stack
|
||||
15
src/.internal/addMapEntry.ts
Normal file
15
src/.internal/addMapEntry.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Adds the key-value `pair` to `map`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} map The map to modify.
|
||||
* @param {Array} pair The key-value pair to add.
|
||||
* @returns {Object} Returns `map`.
|
||||
*/
|
||||
function addMapEntry(map, pair) {
|
||||
// Don't return `map.set` because it's not chainable in IE 11.
|
||||
map.set(pair[0], pair[1])
|
||||
return map
|
||||
}
|
||||
|
||||
export default addMapEntry
|
||||
15
src/.internal/addSetEntry.ts
Normal file
15
src/.internal/addSetEntry.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Adds `value` to `set`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} set The set to modify.
|
||||
* @param {*} value The value to add.
|
||||
* @returns {Object} Returns `set`.
|
||||
*/
|
||||
function addSetEntry(set, value) {
|
||||
// Don't return `set.add` because it's not chainable in IE 11.
|
||||
set.add(value)
|
||||
return set
|
||||
}
|
||||
|
||||
export default addSetEntry
|
||||
21
src/.internal/arrayEach.ts
Normal file
21
src/.internal/arrayEach.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* A specialized version of `forEach` for arrays.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} [array] The array to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @returns {Array} Returns `array`.
|
||||
*/
|
||||
function arrayEach(array, iteratee) {
|
||||
let index = -1
|
||||
const length = array.length
|
||||
|
||||
while (++index < length) {
|
||||
if (iteratee(array[index], index, array) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
export default arrayEach
|
||||
20
src/.internal/arrayEachRight.ts
Normal file
20
src/.internal/arrayEachRight.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* A specialized version of `forEachRight` for arrays.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} [array] The array to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @returns {Array} Returns `array`.
|
||||
*/
|
||||
function arrayEachRight(array, iteratee) {
|
||||
let length = array == null ? 0 : array.length
|
||||
|
||||
while (length--) {
|
||||
if (iteratee(array[length], length, array) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
export default arrayEachRight
|
||||
17
src/.internal/arrayIncludes.ts
Normal file
17
src/.internal/arrayIncludes.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import baseIndexOf from './baseIndexOf.js'
|
||||
|
||||
/**
|
||||
* A specialized version of `includes` for arrays without support for
|
||||
* specifying an index to search from.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} [array] The array to inspect.
|
||||
* @param {*} target The value to search for.
|
||||
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
||||
*/
|
||||
function arrayIncludes(array, value) {
|
||||
const length = array == null ? 0 : array.length
|
||||
return !!length && baseIndexOf(array, value, 0) > -1
|
||||
}
|
||||
|
||||
export default arrayIncludes
|
||||
23
src/.internal/arrayIncludesWith.ts
Normal file
23
src/.internal/arrayIncludesWith.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* This function is like `arrayIncludes` except that it accepts a comparator.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} [array] The array to inspect.
|
||||
* @param {*} target The value to search for.
|
||||
* @param {Function} comparator The comparator invoked per element.
|
||||
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
||||
*/
|
||||
function arrayIncludesWith(array, target, comparator) {
|
||||
if (array == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
for (const value of array) {
|
||||
if (comparator(target, value)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export default arrayIncludesWith
|
||||
43
src/.internal/arrayLikeKeys.ts
Normal file
43
src/.internal/arrayLikeKeys.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import isArguments from '../isArguments.js'
|
||||
import isBuffer from '../isBuffer.js'
|
||||
import isIndex from './isIndex.js'
|
||||
import isTypedArray from '../isTypedArray.js'
|
||||
|
||||
/** Used to check objects for own properties. */
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
/**
|
||||
* Creates an array of the enumerable property names of the array-like `value`.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to query.
|
||||
* @param {boolean} inherited Specify returning inherited property names.
|
||||
* @returns {Array} Returns the array of property names.
|
||||
*/
|
||||
function arrayLikeKeys(value, inherited) {
|
||||
const isArr = Array.isArray(value)
|
||||
const isArg = !isArr && isArguments(value)
|
||||
const isBuff = !isArr && !isArg && isBuffer(value)
|
||||
const isType = !isArr && !isArg && !isBuff && isTypedArray(value)
|
||||
const skipIndexes = isArr || isArg || isBuff || isType
|
||||
const length = value.length
|
||||
const result = new Array(skipIndexes ? length : 0)
|
||||
let index = skipIndexes ? -1 : length
|
||||
while (++index < length) {
|
||||
result[index] = `${index}`
|
||||
}
|
||||
for (const key in value) {
|
||||
if ((inherited || hasOwnProperty.call(value, key)) &&
|
||||
!(skipIndexes && (
|
||||
// Safari 9 has enumerable `arguments.length` in strict mode.
|
||||
(key === 'length' ||
|
||||
// Skip index properties.
|
||||
isIndex(key, length))
|
||||
))) {
|
||||
result.push(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default arrayLikeKeys
|
||||
25
src/.internal/arrayReduce.ts
Normal file
25
src/.internal/arrayReduce.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* A specialized version of `reduce` for arrays.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} [array] The array to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @param {*} [accumulator] The initial value.
|
||||
* @param {boolean} [initAccum] Specify using the first element of `array` as
|
||||
* the initial value.
|
||||
* @returns {*} Returns the accumulated value.
|
||||
*/
|
||||
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
||||
let index = -1
|
||||
const length = array == null ? 0 : array.length
|
||||
|
||||
if (initAccum && length) {
|
||||
accumulator = array[++index]
|
||||
}
|
||||
while (++index < length) {
|
||||
accumulator = iteratee(accumulator, array[index], index, array)
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
export default arrayReduce
|
||||
23
src/.internal/arrayReduceRight.ts
Normal file
23
src/.internal/arrayReduceRight.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* A specialized version of `reduceRight` for arrays.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} [array] The array to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @param {*} [accumulator] The initial value.
|
||||
* @param {boolean} [initAccum] Specify using the last element of `array` as
|
||||
* the initial value.
|
||||
* @returns {*} Returns the accumulated value.
|
||||
*/
|
||||
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
|
||||
let length = array == null ? 0 : array.length
|
||||
if (initAccum && length) {
|
||||
accumulator = array[--length]
|
||||
}
|
||||
while (length--) {
|
||||
accumulator = iteratee(accumulator, array[length], length, array)
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
export default arrayReduceRight
|
||||
12
src/.internal/asciiSize.ts
Normal file
12
src/.internal/asciiSize.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Gets the size of an ASCII `string`.
|
||||
*
|
||||
* @private
|
||||
* @param {string} string The string inspect.
|
||||
* @returns {number} Returns the string size.
|
||||
*/
|
||||
function asciiSize({ length }) {
|
||||
return length
|
||||
}
|
||||
|
||||
export default asciiSize
|
||||
12
src/.internal/asciiToArray.ts
Normal file
12
src/.internal/asciiToArray.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Converts an ASCII `string` to an array.
|
||||
*
|
||||
* @private
|
||||
* @param {string} string The string to convert.
|
||||
* @returns {Array} Returns the converted array.
|
||||
*/
|
||||
function asciiToArray(string) {
|
||||
return string.split('')
|
||||
}
|
||||
|
||||
export default asciiToArray
|
||||
20
src/.internal/assignMergeValue.ts
Normal file
20
src/.internal/assignMergeValue.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import baseAssignValue from './baseAssignValue.js'
|
||||
import eq from '../eq.js'
|
||||
|
||||
/**
|
||||
* This function is like `assignValue` except that it doesn't assign
|
||||
* `undefined` values.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to modify.
|
||||
* @param {string} key The key of the property to assign.
|
||||
* @param {*} value The value to assign.
|
||||
*/
|
||||
function assignMergeValue(object, key, value) {
|
||||
if ((value !== undefined && !eq(object[key], value)) ||
|
||||
(value === undefined && !(key in object))) {
|
||||
baseAssignValue(object, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
export default assignMergeValue
|
||||
27
src/.internal/assignValue.ts
Normal file
27
src/.internal/assignValue.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import baseAssignValue from './baseAssignValue.js'
|
||||
import eq from '../eq.js'
|
||||
|
||||
/** Used to check objects for own properties. */
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
/**
|
||||
* Assigns `value` to `key` of `object` if the existing value is not equivalent.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to modify.
|
||||
* @param {string} key The key of the property to assign.
|
||||
* @param {*} value The value to assign.
|
||||
*/
|
||||
function assignValue(object, key, value) {
|
||||
const objValue = object[key]
|
||||
|
||||
if (!(hasOwnProperty.call(object, key) && eq(objValue, value))) {
|
||||
if (value !== 0 || (1 / value) === (1 / objValue)) {
|
||||
baseAssignValue(object, key, value)
|
||||
}
|
||||
} else if (value === undefined && !(key in object)) {
|
||||
baseAssignValue(object, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
export default assignValue
|
||||
21
src/.internal/assocIndexOf.ts
Normal file
21
src/.internal/assocIndexOf.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import eq from '../eq.js'
|
||||
|
||||
/**
|
||||
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {*} key The key to search for.
|
||||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||||
*/
|
||||
function assocIndexOf(array, key) {
|
||||
let { length } = array
|
||||
while (length--) {
|
||||
if (eq(array[length][0], key)) {
|
||||
return length
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
export default assocIndexOf
|
||||
23
src/.internal/baseAssignValue.ts
Normal file
23
src/.internal/baseAssignValue.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* The base implementation of `assignValue` and `assignMergeValue` without
|
||||
* value checks.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to modify.
|
||||
* @param {string} key The key of the property to assign.
|
||||
* @param {*} value The value to assign.
|
||||
*/
|
||||
function baseAssignValue(object, key, value) {
|
||||
if (key == '__proto__') {
|
||||
Object.defineProperty(object, key, {
|
||||
'configurable': true,
|
||||
'enumerable': true,
|
||||
'value': value,
|
||||
'writable': true
|
||||
})
|
||||
} else {
|
||||
object[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
export default baseAssignValue
|
||||
23
src/.internal/baseAt.ts
Normal file
23
src/.internal/baseAt.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import get from '../get.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `at` without support for individual paths.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {string[]} paths The property paths to pick.
|
||||
* @returns {Array} Returns the picked elements.
|
||||
*/
|
||||
function baseAt(object, paths) {
|
||||
let index = -1
|
||||
const length = paths.length
|
||||
const result = new Array(length)
|
||||
const skip = object == null
|
||||
|
||||
while (++index < length) {
|
||||
result[index] = skip ? undefined : get(object, paths[index])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseAt
|
||||
241
src/.internal/baseClone.ts
Normal file
241
src/.internal/baseClone.ts
Normal file
@@ -0,0 +1,241 @@
|
||||
import Stack from './Stack.js'
|
||||
import arrayEach from './arrayEach.js'
|
||||
import assignValue from './assignValue.js'
|
||||
import cloneBuffer from './cloneBuffer.js'
|
||||
import copyArray from './copyArray.js'
|
||||
import copyObject from './copyObject.js'
|
||||
import cloneArrayBuffer from './cloneArrayBuffer.js'
|
||||
import cloneDataView from './cloneDataView.js'
|
||||
import cloneRegExp from './cloneRegExp.js'
|
||||
import cloneSymbol from './cloneSymbol.js'
|
||||
import cloneTypedArray from './cloneTypedArray.js'
|
||||
import copySymbols from './copySymbols.js'
|
||||
import copySymbolsIn from './copySymbolsIn.js'
|
||||
import getAllKeys from './getAllKeys.js'
|
||||
import getAllKeysIn from './getAllKeysIn.js'
|
||||
import getTag from './getTag.js'
|
||||
import initCloneObject from './initCloneObject.js'
|
||||
import isBuffer from '../isBuffer.js'
|
||||
import isObject from '../isObject.js'
|
||||
import isTypedArray from '../isTypedArray.js'
|
||||
import keys from '../keys.js'
|
||||
import keysIn from '../keysIn.js'
|
||||
|
||||
/** Used to compose bitmasks for cloning. */
|
||||
const CLONE_DEEP_FLAG = 1
|
||||
const CLONE_FLAT_FLAG = 2
|
||||
const CLONE_SYMBOLS_FLAG = 4
|
||||
|
||||
/** `Object#toString` result references. */
|
||||
const argsTag = '[object Arguments]'
|
||||
const arrayTag = '[object Array]'
|
||||
const boolTag = '[object Boolean]'
|
||||
const dateTag = '[object Date]'
|
||||
const errorTag = '[object Error]'
|
||||
const mapTag = '[object Map]'
|
||||
const numberTag = '[object Number]'
|
||||
const objectTag = '[object Object]'
|
||||
const regexpTag = '[object RegExp]'
|
||||
const setTag = '[object Set]'
|
||||
const stringTag = '[object String]'
|
||||
const symbolTag = '[object Symbol]'
|
||||
const weakMapTag = '[object WeakMap]'
|
||||
|
||||
const arrayBufferTag = '[object ArrayBuffer]'
|
||||
const dataViewTag = '[object DataView]'
|
||||
const float32Tag = '[object Float32Array]'
|
||||
const float64Tag = '[object Float64Array]'
|
||||
const int8Tag = '[object Int8Array]'
|
||||
const int16Tag = '[object Int16Array]'
|
||||
const int32Tag = '[object Int32Array]'
|
||||
const uint8Tag = '[object Uint8Array]'
|
||||
const uint8ClampedTag = '[object Uint8ClampedArray]'
|
||||
const uint16Tag = '[object Uint16Array]'
|
||||
const uint32Tag = '[object Uint32Array]'
|
||||
|
||||
/** Used to identify `toStringTag` values supported by `clone`. */
|
||||
const cloneableTags = {}
|
||||
cloneableTags[argsTag] = cloneableTags[arrayTag] =
|
||||
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
|
||||
cloneableTags[boolTag] = cloneableTags[dateTag] =
|
||||
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
|
||||
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
|
||||
cloneableTags[int32Tag] = cloneableTags[mapTag] =
|
||||
cloneableTags[numberTag] = cloneableTags[objectTag] =
|
||||
cloneableTags[regexpTag] = cloneableTags[setTag] =
|
||||
cloneableTags[stringTag] = cloneableTags[symbolTag] =
|
||||
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
|
||||
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true
|
||||
cloneableTags[errorTag] = cloneableTags[weakMapTag] = false
|
||||
|
||||
/** Used to check objects for own properties. */
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
/**
|
||||
* Initializes an object clone based on its `toStringTag`.
|
||||
*
|
||||
* **Note:** This function only supports cloning values with tags of
|
||||
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to clone.
|
||||
* @param {string} tag The `toStringTag` of the object to clone.
|
||||
* @param {boolean} [isDeep] Specify a deep clone.
|
||||
* @returns {Object} Returns the initialized clone.
|
||||
*/
|
||||
function initCloneByTag(object, tag, isDeep) {
|
||||
const Ctor = object.constructor
|
||||
switch (tag) {
|
||||
case arrayBufferTag:
|
||||
return cloneArrayBuffer(object)
|
||||
|
||||
case boolTag:
|
||||
case dateTag:
|
||||
return new Ctor(+object)
|
||||
|
||||
case dataViewTag:
|
||||
return cloneDataView(object, isDeep)
|
||||
|
||||
case float32Tag: case float64Tag:
|
||||
case int8Tag: case int16Tag: case int32Tag:
|
||||
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
||||
return cloneTypedArray(object, isDeep)
|
||||
|
||||
case mapTag:
|
||||
return new Ctor
|
||||
|
||||
case numberTag:
|
||||
case stringTag:
|
||||
return new Ctor(object)
|
||||
|
||||
case regexpTag:
|
||||
return cloneRegExp(object)
|
||||
|
||||
case setTag:
|
||||
return new Ctor
|
||||
|
||||
case symbolTag:
|
||||
return cloneSymbol(object)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an array clone.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to clone.
|
||||
* @returns {Array} Returns the initialized clone.
|
||||
*/
|
||||
function initCloneArray(array) {
|
||||
const { length } = array
|
||||
const result = new array.constructor(length)
|
||||
|
||||
// Add properties assigned by `RegExp#exec`.
|
||||
if (length && typeof array[0] === 'string' && hasOwnProperty.call(array, 'index')) {
|
||||
result.index = array.index
|
||||
result.input = array.input
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `clone` and `cloneDeep` which tracks
|
||||
* traversed objects.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to clone.
|
||||
* @param {number} bitmask The bitmask flags.
|
||||
* 1 - Deep clone
|
||||
* 2 - Flatten inherited properties
|
||||
* 4 - Clone symbols
|
||||
* @param {Function} [customizer] The function to customize cloning.
|
||||
* @param {string} [key] The key of `value`.
|
||||
* @param {Object} [object] The parent object of `value`.
|
||||
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
|
||||
* @returns {*} Returns the cloned value.
|
||||
*/
|
||||
function baseClone(value, bitmask, customizer, key, object, stack) {
|
||||
let result
|
||||
const isDeep = bitmask & CLONE_DEEP_FLAG
|
||||
const isFlat = bitmask & CLONE_FLAT_FLAG
|
||||
const isFull = bitmask & CLONE_SYMBOLS_FLAG
|
||||
|
||||
if (customizer) {
|
||||
result = object ? customizer(value, key, object, stack) : customizer(value)
|
||||
}
|
||||
if (result !== undefined) {
|
||||
return result
|
||||
}
|
||||
if (!isObject(value)) {
|
||||
return value
|
||||
}
|
||||
const isArr = Array.isArray(value)
|
||||
const tag = getTag(value)
|
||||
if (isArr) {
|
||||
result = initCloneArray(value)
|
||||
if (!isDeep) {
|
||||
return copyArray(value, result)
|
||||
}
|
||||
} else {
|
||||
const isFunc = typeof value === 'function'
|
||||
|
||||
if (isBuffer(value)) {
|
||||
return cloneBuffer(value, isDeep)
|
||||
}
|
||||
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
|
||||
result = (isFlat || isFunc) ? {} : initCloneObject(value)
|
||||
if (!isDeep) {
|
||||
return isFlat
|
||||
? copySymbolsIn(value, copyObject(value, keysIn(value), result))
|
||||
: copySymbols(value, Object.assign(result, value))
|
||||
}
|
||||
} else {
|
||||
if (isFunc || !cloneableTags[tag]) {
|
||||
return object ? value : {}
|
||||
}
|
||||
result = initCloneByTag(value, tag, isDeep)
|
||||
}
|
||||
}
|
||||
// Check for circular references and return its corresponding clone.
|
||||
stack || (stack = new Stack)
|
||||
const stacked = stack.get(value)
|
||||
if (stacked) {
|
||||
return stacked
|
||||
}
|
||||
stack.set(value, result)
|
||||
|
||||
if (tag == mapTag) {
|
||||
value.forEach((subValue, key) => {
|
||||
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack))
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
if (tag == setTag) {
|
||||
value.forEach((subValue) => {
|
||||
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack))
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
if (isTypedArray(value)) {
|
||||
return result
|
||||
}
|
||||
|
||||
const keysFunc = isFull
|
||||
? (isFlat ? getAllKeysIn : getAllKeys)
|
||||
: (isFlat ? keysIn : keys)
|
||||
|
||||
const props = isArr ? undefined : keysFunc(value)
|
||||
arrayEach(props || value, (subValue, key) => {
|
||||
if (props) {
|
||||
key = subValue
|
||||
subValue = value[key]
|
||||
}
|
||||
// Recursively populate clone (susceptible to call stack limits).
|
||||
assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack))
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseClone
|
||||
16
src/.internal/baseConforms.ts
Normal file
16
src/.internal/baseConforms.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import baseConformsTo from './baseConformsTo.js'
|
||||
import keys from '../keys.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `conforms` which doesn't clone `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} source The object of property predicates to conform to.
|
||||
* @returns {Function} Returns the new spec function.
|
||||
*/
|
||||
function baseConforms(source) {
|
||||
const props = keys(source)
|
||||
return (object) => baseConformsTo(object, source, props)
|
||||
}
|
||||
|
||||
export default baseConforms
|
||||
27
src/.internal/baseConformsTo.ts
Normal file
27
src/.internal/baseConformsTo.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* The base implementation of `conformsTo` which accepts `props` to check.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to inspect.
|
||||
* @param {Object} source The object of property predicates to conform to.
|
||||
* @returns {boolean} Returns `true` if `object` conforms, else `false`.
|
||||
*/
|
||||
function baseConformsTo(object, source, props) {
|
||||
let length = props.length
|
||||
if (object == null) {
|
||||
return !length
|
||||
}
|
||||
object = Object(object)
|
||||
while (length--) {
|
||||
const key = props[length]
|
||||
const predicate = source[key]
|
||||
const value = object[key]
|
||||
|
||||
if ((value === undefined && !(key in object)) || !predicate(value)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export default baseConformsTo
|
||||
63
src/.internal/baseDifference.ts
Normal file
63
src/.internal/baseDifference.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import SetCache from './SetCache.js'
|
||||
import arrayIncludes from './arrayIncludes.js'
|
||||
import arrayIncludesWith from './arrayIncludesWith.js'
|
||||
import map from '../map.js'
|
||||
import cacheHas from './cacheHas.js'
|
||||
|
||||
/** Used as the size to enable large array optimizations. */
|
||||
const LARGE_ARRAY_SIZE = 200
|
||||
|
||||
/**
|
||||
* The base implementation of methods like `difference` without support
|
||||
* for excluding multiple arrays.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {Array} values The values to exclude.
|
||||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||||
* @param {Function} [comparator] The comparator invoked per element.
|
||||
* @returns {Array} Returns the new array of filtered values.
|
||||
*/
|
||||
function baseDifference(array, values, iteratee, comparator) {
|
||||
let includes = arrayIncludes
|
||||
let isCommon = true
|
||||
const result = []
|
||||
const valuesLength = values.length
|
||||
|
||||
if (!array.length) {
|
||||
return result
|
||||
}
|
||||
if (iteratee) {
|
||||
values = map(values, (value) => iteratee(value))
|
||||
}
|
||||
if (comparator) {
|
||||
includes = arrayIncludesWith
|
||||
isCommon = false
|
||||
}
|
||||
else if (values.length >= LARGE_ARRAY_SIZE) {
|
||||
includes = cacheHas
|
||||
isCommon = false
|
||||
values = new SetCache(values)
|
||||
}
|
||||
outer:
|
||||
for (let value of array) {
|
||||
const computed = iteratee == null ? value : iteratee(value)
|
||||
|
||||
value = (comparator || value !== 0) ? value : 0
|
||||
if (isCommon && computed === computed) {
|
||||
let valuesIndex = valuesLength
|
||||
while (valuesIndex--) {
|
||||
if (values[valuesIndex] === computed) {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
result.push(value)
|
||||
}
|
||||
else if (!includes(values, computed, comparator)) {
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseDifference
|
||||
31
src/.internal/baseEach.ts
Normal file
31
src/.internal/baseEach.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import baseForOwn from './baseForOwn.js'
|
||||
import isArrayLike from '../isArrayLike.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `forEach`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object} collection The collection to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @returns {Array|Object} Returns `collection`.
|
||||
*/
|
||||
function baseEach(collection, iteratee) {
|
||||
if (collection == null) {
|
||||
return collection
|
||||
}
|
||||
if (!isArrayLike(collection)) {
|
||||
return baseForOwn(collection, iteratee)
|
||||
}
|
||||
const length = collection.length
|
||||
const iterable = Object(collection)
|
||||
let index = -1
|
||||
|
||||
while (++index < length) {
|
||||
if (iteratee(iterable[index], index, iterable) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return collection
|
||||
}
|
||||
|
||||
export default baseEach
|
||||
30
src/.internal/baseEachRight.ts
Normal file
30
src/.internal/baseEachRight.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import baseForOwnRight from './baseForOwnRight.js'
|
||||
import isArrayLike from '../isArrayLike.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `forEachRight`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object} collection The collection to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @returns {Array|Object} Returns `collection`.
|
||||
*/
|
||||
function baseEachRight(collection, iteratee) {
|
||||
if (collection == null) {
|
||||
return collection
|
||||
}
|
||||
if (!isArrayLike(collection)) {
|
||||
return baseForOwnRight(collection, iteratee)
|
||||
}
|
||||
const iterable = Object(collection)
|
||||
let length = collection.length
|
||||
|
||||
while (length--) {
|
||||
if (iteratee(iterable[length], length, iterable) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return collection
|
||||
}
|
||||
|
||||
export default baseEachRight
|
||||
23
src/.internal/baseFindIndex.ts
Normal file
23
src/.internal/baseFindIndex.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* The base implementation of `findIndex` and `findLastIndex`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {Function} predicate The function invoked per iteration.
|
||||
* @param {number} fromIndex The index to search from.
|
||||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||||
*/
|
||||
function baseFindIndex(array, predicate, fromIndex, fromRight) {
|
||||
const { length } = array
|
||||
let index = fromIndex + (fromRight ? 1 : -1)
|
||||
|
||||
while ((fromRight ? index-- : ++index < length)) {
|
||||
if (predicate(array[index], index, array)) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
export default baseFindIndex
|
||||
22
src/.internal/baseFindKey.ts
Normal file
22
src/.internal/baseFindKey.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The base implementation of methods like `findKey` and `findLastKey`
|
||||
* which iterates over `collection` using `eachFunc`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object} collection The collection to inspect.
|
||||
* @param {Function} predicate The function invoked per iteration.
|
||||
* @param {Function} eachFunc The function to iterate over `collection`.
|
||||
* @returns {*} Returns the found element or its key, else `undefined`.
|
||||
*/
|
||||
function baseFindKey(collection, predicate, eachFunc) {
|
||||
let result
|
||||
eachFunc(collection, (value, key, collection) => {
|
||||
if (predicate(value, key, collection)) {
|
||||
result = key
|
||||
return false
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseFindKey
|
||||
37
src/.internal/baseFlatten.ts
Normal file
37
src/.internal/baseFlatten.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import isFlattenable from './isFlattenable.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `flatten` with support for restricting flattening.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to flatten.
|
||||
* @param {number} depth The maximum recursion depth.
|
||||
* @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
|
||||
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
|
||||
* @param {Array} [result=[]] The initial result value.
|
||||
* @returns {Array} Returns the new flattened array.
|
||||
*/
|
||||
function baseFlatten(array, depth, predicate, isStrict, result) {
|
||||
predicate || (predicate = isFlattenable)
|
||||
result || (result = [])
|
||||
|
||||
if (array == null) {
|
||||
return result
|
||||
}
|
||||
|
||||
for (const value of array) {
|
||||
if (depth > 0 && predicate(value)) {
|
||||
if (depth > 1) {
|
||||
// Recursively flatten arrays (susceptible to call stack limits).
|
||||
baseFlatten(value, depth - 1, predicate, isStrict, result)
|
||||
} else {
|
||||
result.push(...value)
|
||||
}
|
||||
} else if (!isStrict) {
|
||||
result[result.length] = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseFlatten
|
||||
27
src/.internal/baseFor.ts
Normal file
27
src/.internal/baseFor.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* The base implementation of `baseForOwn` which iterates over `object`
|
||||
* properties returned by `keysFunc` and invokes `iteratee` for each property.
|
||||
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @param {Function} keysFunc The function to get the keys of `object`.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function baseFor(object, iteratee, keysFunc) {
|
||||
const iterable = Object(object)
|
||||
const props = keysFunc(object)
|
||||
let { length } = props
|
||||
let index = -1
|
||||
|
||||
while (length--) {
|
||||
const key = props[++index]
|
||||
if (iteratee(iterable[key], key, iterable) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
||||
export default baseFor
|
||||
16
src/.internal/baseForOwn.ts
Normal file
16
src/.internal/baseForOwn.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import baseFor from './baseFor.js'
|
||||
import keys from '../keys.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `forOwn`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function baseForOwn(object, iteratee) {
|
||||
return object && baseFor(object, iteratee, keys)
|
||||
}
|
||||
|
||||
export default baseForOwn
|
||||
16
src/.internal/baseForOwnRight.ts
Normal file
16
src/.internal/baseForOwnRight.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import baseForRight from './baseForRight.js'
|
||||
import keys from '../keys.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `forOwnRight`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function baseForOwnRight(object, iteratee) {
|
||||
return object && baseForRight(object, iteratee, keys)
|
||||
}
|
||||
|
||||
export default baseForOwnRight
|
||||
25
src/.internal/baseForRight.ts
Normal file
25
src/.internal/baseForRight.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* This function is like `baseFor` except that it iterates over properties
|
||||
* in the opposite order.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @param {Function} keysFunc The function to get the keys of `object`.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function baseForRight(object, iteratee, keysFunc) {
|
||||
const iterable = Object(object)
|
||||
const props = keysFunc(object)
|
||||
let { length } = props
|
||||
|
||||
while (length--) {
|
||||
const key = props[length]
|
||||
if (iteratee(iterable[key], key, iterable) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
||||
export default baseForRight
|
||||
24
src/.internal/baseGet.ts
Normal file
24
src/.internal/baseGet.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import castPath from './castPath.js'
|
||||
import toKey from './toKey.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `get` without support for default values.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to query.
|
||||
* @param {Array|string} path The path of the property to get.
|
||||
* @returns {*} Returns the resolved value.
|
||||
*/
|
||||
function baseGet(object, path) {
|
||||
path = castPath(path, object)
|
||||
|
||||
let index = 0
|
||||
const length = path.length
|
||||
|
||||
while (object != null && index < length) {
|
||||
object = object[toKey(path[index++])]
|
||||
}
|
||||
return (index && index == length) ? object : undefined
|
||||
}
|
||||
|
||||
export default baseGet
|
||||
14
src/.internal/baseInRange.ts
Normal file
14
src/.internal/baseInRange.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* The base implementation of `inRange` which doesn't coerce arguments.
|
||||
*
|
||||
* @private
|
||||
* @param {number} number The number to check.
|
||||
* @param {number} start The start of the range.
|
||||
* @param {number} end The end of the range.
|
||||
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
|
||||
*/
|
||||
function baseInRange(number, start, end) {
|
||||
return number >= Math.min(start, end) && number < Math.max(start, end)
|
||||
}
|
||||
|
||||
export default baseInRange
|
||||
20
src/.internal/baseIndexOf.ts
Normal file
20
src/.internal/baseIndexOf.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import baseFindIndex from './baseFindIndex.js'
|
||||
import baseIsNaN from './baseIsNaN.js'
|
||||
import strictIndexOf from './strictIndexOf.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `indexOf` without `fromIndex` bounds checks.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {*} value The value to search for.
|
||||
* @param {number} fromIndex The index to search from.
|
||||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||||
*/
|
||||
function baseIndexOf(array, value, fromIndex) {
|
||||
return value === value
|
||||
? strictIndexOf(array, value, fromIndex)
|
||||
: baseFindIndex(array, baseIsNaN, fromIndex)
|
||||
}
|
||||
|
||||
export default baseIndexOf
|
||||
23
src/.internal/baseIndexOfWith.ts
Normal file
23
src/.internal/baseIndexOfWith.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* This function is like `baseIndexOf` except that it accepts a comparator.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {*} value The value to search for.
|
||||
* @param {number} fromIndex The index to search from.
|
||||
* @param {Function} comparator The comparator invoked per element.
|
||||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||||
*/
|
||||
function baseIndexOfWith(array, value, fromIndex, comparator) {
|
||||
let index = fromIndex - 1
|
||||
const { length } = array
|
||||
|
||||
while (++index < length) {
|
||||
if (comparator(array[index], value)) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
export default baseIndexOfWith
|
||||
72
src/.internal/baseIntersection.ts
Normal file
72
src/.internal/baseIntersection.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import SetCache from './SetCache.js'
|
||||
import arrayIncludes from './arrayIncludes.js'
|
||||
import arrayIncludesWith from './arrayIncludesWith.js'
|
||||
import map from '../map.js'
|
||||
import cacheHas from './cacheHas.js'
|
||||
|
||||
/**
|
||||
* The base implementation of methods like `intersection` that accepts an
|
||||
* array of arrays to inspect.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} arrays The arrays to inspect.
|
||||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||||
* @param {Function} [comparator] The comparator invoked per element.
|
||||
* @returns {Array} Returns the new array of shared values.
|
||||
*/
|
||||
function baseIntersection(arrays, iteratee, comparator) {
|
||||
const includes = comparator ? arrayIncludesWith : arrayIncludes
|
||||
const length = arrays[0].length
|
||||
const othLength = arrays.length
|
||||
const caches = new Array(othLength)
|
||||
const result = []
|
||||
|
||||
let array
|
||||
let maxLength = Infinity
|
||||
let othIndex = othLength
|
||||
|
||||
while (othIndex--) {
|
||||
array = arrays[othIndex]
|
||||
if (othIndex && iteratee) {
|
||||
array = map(array, (value) => iteratee(value))
|
||||
}
|
||||
maxLength = Math.min(array.length, maxLength)
|
||||
caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
|
||||
? new SetCache(othIndex && array)
|
||||
: undefined
|
||||
}
|
||||
array = arrays[0]
|
||||
|
||||
let index = -1
|
||||
const seen = caches[0]
|
||||
|
||||
outer:
|
||||
while (++index < length && result.length < maxLength) {
|
||||
let value = array[index]
|
||||
const computed = iteratee ? iteratee(value) : value
|
||||
|
||||
value = (comparator || value !== 0) ? value : 0
|
||||
if (!(seen
|
||||
? cacheHas(seen, computed)
|
||||
: includes(result, computed, comparator)
|
||||
)) {
|
||||
othIndex = othLength
|
||||
while (--othIndex) {
|
||||
const cache = caches[othIndex]
|
||||
if (!(cache
|
||||
? cacheHas(cache, computed)
|
||||
: includes(arrays[othIndex], computed, comparator))
|
||||
) {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
if (seen) {
|
||||
seen.push(computed)
|
||||
}
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseIntersection
|
||||
28
src/.internal/baseIsEqual.ts
Normal file
28
src/.internal/baseIsEqual.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import baseIsEqualDeep from './baseIsEqualDeep.js'
|
||||
import isObjectLike from '../isObjectLike.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `isEqual` which supports partial comparisons
|
||||
* and tracks traversed objects.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to compare.
|
||||
* @param {*} other The other value to compare.
|
||||
* @param {boolean} bitmask The bitmask flags.
|
||||
* 1 - Unordered comparison
|
||||
* 2 - Partial comparison
|
||||
* @param {Function} [customizer] The function to customize comparisons.
|
||||
* @param {Object} [stack] Tracks traversed `value` and `other` objects.
|
||||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||||
*/
|
||||
function baseIsEqual(value, other, bitmask, customizer, stack) {
|
||||
if (value === other) {
|
||||
return true
|
||||
}
|
||||
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
|
||||
return value !== value && other !== other
|
||||
}
|
||||
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack)
|
||||
}
|
||||
|
||||
export default baseIsEqual
|
||||
79
src/.internal/baseIsEqualDeep.ts
Normal file
79
src/.internal/baseIsEqualDeep.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import Stack from './Stack.js'
|
||||
import equalArrays from './equalArrays.js'
|
||||
import equalByTag from './equalByTag.js'
|
||||
import equalObjects from './equalObjects.js'
|
||||
import getTag from './getTag.js'
|
||||
import isBuffer from '../isBuffer.js'
|
||||
import isTypedArray from '../isTypedArray.js'
|
||||
|
||||
/** Used to compose bitmasks for value comparisons. */
|
||||
const COMPARE_PARTIAL_FLAG = 1
|
||||
|
||||
/** `Object#toString` result references. */
|
||||
const argsTag = '[object Arguments]'
|
||||
const arrayTag = '[object Array]'
|
||||
const objectTag = '[object Object]'
|
||||
|
||||
/** Used to check objects for own properties. */
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
/**
|
||||
* A specialized version of `baseIsEqual` for arrays and objects which performs
|
||||
* deep comparisons and tracks traversed objects enabling objects with circular
|
||||
* references to be compared.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to compare.
|
||||
* @param {Object} other The other object to compare.
|
||||
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
||||
* @param {Function} customizer The function to customize comparisons.
|
||||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||||
* @param {Object} [stack] Tracks traversed `object` and `other` objects.
|
||||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||||
*/
|
||||
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
|
||||
let objIsArr = Array.isArray(object)
|
||||
const othIsArr = Array.isArray(other)
|
||||
let objTag = objIsArr ? arrayTag : getTag(object)
|
||||
let othTag = othIsArr ? arrayTag : getTag(other)
|
||||
|
||||
objTag = objTag == argsTag ? objectTag : objTag
|
||||
othTag = othTag == argsTag ? objectTag : othTag
|
||||
|
||||
let objIsObj = objTag == objectTag
|
||||
const othIsObj = othTag == objectTag
|
||||
const isSameTag = objTag == othTag
|
||||
|
||||
if (isSameTag && isBuffer(object)) {
|
||||
if (!isBuffer(other)) {
|
||||
return false
|
||||
}
|
||||
objIsArr = true
|
||||
objIsObj = false
|
||||
}
|
||||
if (isSameTag && !objIsObj) {
|
||||
stack || (stack = new Stack)
|
||||
return (objIsArr || isTypedArray(object))
|
||||
? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
|
||||
: equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack)
|
||||
}
|
||||
if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
|
||||
const objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__')
|
||||
const othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__')
|
||||
|
||||
if (objIsWrapped || othIsWrapped) {
|
||||
const objUnwrapped = objIsWrapped ? object.value() : object
|
||||
const othUnwrapped = othIsWrapped ? other.value() : other
|
||||
|
||||
stack || (stack = new Stack)
|
||||
return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack)
|
||||
}
|
||||
}
|
||||
if (!isSameTag) {
|
||||
return false
|
||||
}
|
||||
stack || (stack = new Stack)
|
||||
return equalObjects(object, other, bitmask, customizer, equalFunc, stack)
|
||||
}
|
||||
|
||||
export default baseIsEqualDeep
|
||||
64
src/.internal/baseIsMatch.ts
Normal file
64
src/.internal/baseIsMatch.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import Stack from './Stack.js'
|
||||
import baseIsEqual from './baseIsEqual.js'
|
||||
|
||||
/** Used to compose bitmasks for value comparisons. */
|
||||
const COMPARE_PARTIAL_FLAG = 1
|
||||
const COMPARE_UNORDERED_FLAG = 2
|
||||
|
||||
/**
|
||||
* The base implementation of `isMatch`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to inspect.
|
||||
* @param {Object} source The object of property values to match.
|
||||
* @param {Array} matchData The property names, values, and compare flags to match.
|
||||
* @param {Function} [customizer] The function to customize comparisons.
|
||||
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
||||
*/
|
||||
function baseIsMatch(object, source, matchData, customizer) {
|
||||
let index = matchData.length
|
||||
const length = index
|
||||
const noCustomizer = !customizer
|
||||
|
||||
if (object == null) {
|
||||
return !length
|
||||
}
|
||||
let data
|
||||
let result
|
||||
object = Object(object)
|
||||
while (index--) {
|
||||
data = matchData[index]
|
||||
if ((noCustomizer && data[2])
|
||||
? data[1] !== object[data[0]]
|
||||
: !(data[0] in object)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
while (++index < length) {
|
||||
data = matchData[index]
|
||||
const key = data[0]
|
||||
const objValue = object[key]
|
||||
const srcValue = data[1]
|
||||
|
||||
if (noCustomizer && data[2]) {
|
||||
if (objValue === undefined && !(key in object)) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
const stack = new Stack
|
||||
if (customizer) {
|
||||
result = customizer(objValue, srcValue, key, object, source, stack)
|
||||
}
|
||||
if (!(result === undefined
|
||||
? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
|
||||
: result
|
||||
)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export default baseIsMatch
|
||||
12
src/.internal/baseIsNaN.ts
Normal file
12
src/.internal/baseIsNaN.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* The base implementation of `isNaN` without support for number objects.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
||||
*/
|
||||
function baseIsNaN(value) {
|
||||
return value !== value
|
||||
}
|
||||
|
||||
export default baseIsNaN
|
||||
20
src/.internal/baseMatches.ts
Normal file
20
src/.internal/baseMatches.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import baseIsMatch from './baseIsMatch.js'
|
||||
import getMatchData from './getMatchData.js'
|
||||
import matchesStrictComparable from './matchesStrictComparable.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `matches` which doesn't clone `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} source The object of property values to match.
|
||||
* @returns {Function} Returns the new spec function.
|
||||
*/
|
||||
function baseMatches(source) {
|
||||
const matchData = getMatchData(source)
|
||||
if (matchData.length === 1 && matchData[0][2]) {
|
||||
return matchesStrictComparable(matchData[0][0], matchData[0][1])
|
||||
}
|
||||
return (object) => object === source || baseIsMatch(object, source, matchData)
|
||||
}
|
||||
|
||||
export default baseMatches
|
||||
33
src/.internal/baseMatchesProperty.ts
Normal file
33
src/.internal/baseMatchesProperty.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import baseIsEqual from './baseIsEqual.js'
|
||||
import get from '../get.js'
|
||||
import hasIn from '../hasIn.js'
|
||||
import isKey from './isKey.js'
|
||||
import isStrictComparable from './isStrictComparable.js'
|
||||
import matchesStrictComparable from './matchesStrictComparable.js'
|
||||
import toKey from './toKey.js'
|
||||
|
||||
/** Used to compose bitmasks for value comparisons. */
|
||||
const COMPARE_PARTIAL_FLAG = 1
|
||||
const COMPARE_UNORDERED_FLAG = 2
|
||||
|
||||
/**
|
||||
* The base implementation of `matchesProperty` which doesn't clone `srcValue`.
|
||||
*
|
||||
* @private
|
||||
* @param {string} path The path of the property to get.
|
||||
* @param {*} srcValue The value to match.
|
||||
* @returns {Function} Returns the new spec function.
|
||||
*/
|
||||
function baseMatchesProperty(path, srcValue) {
|
||||
if (isKey(path) && isStrictComparable(srcValue)) {
|
||||
return matchesStrictComparable(toKey(path), srcValue)
|
||||
}
|
||||
return (object) => {
|
||||
const objValue = get(object, path)
|
||||
return (objValue === undefined && objValue === srcValue)
|
||||
? hasIn(object, path)
|
||||
: baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG)
|
||||
}
|
||||
}
|
||||
|
||||
export default baseMatchesProperty
|
||||
41
src/.internal/baseMerge.ts
Normal file
41
src/.internal/baseMerge.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import Stack from './Stack.js'
|
||||
import assignMergeValue from './assignMergeValue.js'
|
||||
import baseFor from './baseFor.js'
|
||||
import baseMergeDeep from './baseMergeDeep.js'
|
||||
import isObject from '../isObject.js'
|
||||
import keysIn from '../keysIn.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `merge` without support for multiple sources.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The destination object.
|
||||
* @param {Object} source The source object.
|
||||
* @param {number} srcIndex The index of `source`.
|
||||
* @param {Function} [customizer] The function to customize merged values.
|
||||
* @param {Object} [stack] Tracks traversed source values and their merged
|
||||
* counterparts.
|
||||
*/
|
||||
function baseMerge(object, source, srcIndex, customizer, stack) {
|
||||
if (object === source) {
|
||||
return
|
||||
}
|
||||
baseFor(source, (srcValue, key) => {
|
||||
if (isObject(srcValue)) {
|
||||
stack || (stack = new Stack)
|
||||
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack)
|
||||
}
|
||||
else {
|
||||
let newValue = customizer
|
||||
? customizer(object[key], srcValue, `${key}`, object, source, stack)
|
||||
: undefined
|
||||
|
||||
if (newValue === undefined) {
|
||||
newValue = srcValue
|
||||
}
|
||||
assignMergeValue(object, key, newValue)
|
||||
}
|
||||
}, keysIn)
|
||||
}
|
||||
|
||||
export default baseMerge
|
||||
91
src/.internal/baseMergeDeep.ts
Normal file
91
src/.internal/baseMergeDeep.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import assignMergeValue from './assignMergeValue.js'
|
||||
import cloneBuffer from './cloneBuffer.js'
|
||||
import cloneTypedArray from './cloneTypedArray.js'
|
||||
import copyArray from './copyArray.js'
|
||||
import initCloneObject from './initCloneObject.js'
|
||||
import isArguments from '../isArguments.js'
|
||||
import isArrayLikeObject from '../isArrayLikeObject.js'
|
||||
import isBuffer from '../isBuffer.js'
|
||||
import isObject from '../isObject.js'
|
||||
import isPlainObject from '../isPlainObject.js'
|
||||
import isTypedArray from '../isTypedArray.js'
|
||||
import toPlainObject from '../toPlainObject.js'
|
||||
|
||||
/**
|
||||
* A specialized version of `baseMerge` for arrays and objects which performs
|
||||
* deep merges and tracks traversed objects enabling objects with circular
|
||||
* references to be merged.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The destination object.
|
||||
* @param {Object} source The source object.
|
||||
* @param {string} key The key of the value to merge.
|
||||
* @param {number} srcIndex The index of `source`.
|
||||
* @param {Function} mergeFunc The function to merge values.
|
||||
* @param {Function} [customizer] The function to customize assigned values.
|
||||
* @param {Object} [stack] Tracks traversed source values and their merged
|
||||
* counterparts.
|
||||
*/
|
||||
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
||||
const objValue = object[key]
|
||||
const srcValue = source[key]
|
||||
const stacked = stack.get(srcValue)
|
||||
|
||||
if (stacked) {
|
||||
assignMergeValue(object, key, stacked)
|
||||
return
|
||||
}
|
||||
let newValue = customizer
|
||||
? customizer(objValue, srcValue, `${key}`, object, source, stack)
|
||||
: undefined
|
||||
|
||||
let isCommon = newValue === undefined
|
||||
|
||||
if (isCommon) {
|
||||
const isArr = Array.isArray(srcValue)
|
||||
const isBuff = !isArr && isBuffer(srcValue)
|
||||
const isTyped = !isArr && !isBuff && isTypedArray(srcValue)
|
||||
|
||||
newValue = srcValue
|
||||
if (isArr || isBuff || isTyped) {
|
||||
if (Array.isArray(objValue)) {
|
||||
newValue = objValue
|
||||
}
|
||||
else if (isArrayLikeObject(objValue)) {
|
||||
newValue = copyArray(objValue)
|
||||
}
|
||||
else if (isBuff) {
|
||||
isCommon = false
|
||||
newValue = cloneBuffer(srcValue, true)
|
||||
}
|
||||
else if (isTyped) {
|
||||
isCommon = false
|
||||
newValue = cloneTypedArray(srcValue, true)
|
||||
}
|
||||
else {
|
||||
newValue = []
|
||||
}
|
||||
}
|
||||
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
||||
newValue = objValue
|
||||
if (isArguments(objValue)) {
|
||||
newValue = toPlainObject(objValue)
|
||||
}
|
||||
else if (typeof objValue === 'function' || !isObject(objValue)) {
|
||||
newValue = initCloneObject(srcValue)
|
||||
}
|
||||
}
|
||||
else {
|
||||
isCommon = false
|
||||
}
|
||||
}
|
||||
if (isCommon) {
|
||||
// Recursively merge objects and arrays (susceptible to call stack limits).
|
||||
stack.set(srcValue, newValue)
|
||||
mergeFunc(newValue, srcValue, srcIndex, customizer, stack)
|
||||
stack['delete'](srcValue)
|
||||
}
|
||||
assignMergeValue(object, key, newValue)
|
||||
}
|
||||
|
||||
export default baseMergeDeep
|
||||
49
src/.internal/baseOrderBy.ts
Normal file
49
src/.internal/baseOrderBy.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import baseEach from './baseEach.js'
|
||||
import baseSortBy from './baseSortBy.js'
|
||||
import baseGet from './baseGet.js'
|
||||
import compareMultiple from './compareMultiple.js'
|
||||
import isArrayLike from '../isArrayLike.js'
|
||||
|
||||
const identity = (value) => value
|
||||
|
||||
/**
|
||||
* The base implementation of `orderBy` without param guards.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object} collection The collection to iterate over.
|
||||
* @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
|
||||
* @param {string[]} orders The sort orders of `iteratees`.
|
||||
* @returns {Array} Returns the new sorted array.
|
||||
*/
|
||||
function baseOrderBy(collection, iteratees, orders) {
|
||||
if (iteratees.length) {
|
||||
iteratees = iteratees.map((iteratee) => {
|
||||
if (Array.isArray(iteratee)) {
|
||||
return (value) => baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee)
|
||||
}
|
||||
|
||||
return iteratee
|
||||
})
|
||||
} else {
|
||||
iteratees = [identity]
|
||||
}
|
||||
|
||||
let criteriaIndex = -1
|
||||
let eachIndex = -1
|
||||
|
||||
const result = isArrayLike(collection) ? new Array(collection.length) : []
|
||||
|
||||
baseEach(collection, (value) => {
|
||||
const criteria = iteratees.map((iteratee) => iteratee(value))
|
||||
|
||||
result[++eachIndex] = {
|
||||
criteria,
|
||||
index: ++criteriaIndex,
|
||||
value
|
||||
}
|
||||
})
|
||||
|
||||
return baseSortBy(result, (object, other) => compareMultiple(object, other, orders))
|
||||
}
|
||||
|
||||
export default baseOrderBy
|
||||
17
src/.internal/basePick.ts
Normal file
17
src/.internal/basePick.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import basePickBy from './basePickBy.js'
|
||||
import hasIn from '../hasIn.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `pick` without support for individual
|
||||
* property identifiers.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The source object.
|
||||
* @param {string[]} paths The property paths to pick.
|
||||
* @returns {Object} Returns the new object.
|
||||
*/
|
||||
function basePick(object, paths) {
|
||||
return basePickBy(object, paths, (value, path) => hasIn(object, path))
|
||||
}
|
||||
|
||||
export default basePick
|
||||
29
src/.internal/basePickBy.ts
Normal file
29
src/.internal/basePickBy.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import baseGet from './baseGet.js'
|
||||
import baseSet from './baseSet.js'
|
||||
import castPath from './castPath.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `pickBy`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The source object.
|
||||
* @param {string[]} paths The property paths to pick.
|
||||
* @param {Function} predicate The function invoked per property.
|
||||
* @returns {Object} Returns the new object.
|
||||
*/
|
||||
function basePickBy(object, paths, predicate) {
|
||||
let index = -1
|
||||
const length = paths.length
|
||||
const result = {}
|
||||
|
||||
while (++index < length) {
|
||||
const path = paths[index]
|
||||
const value = baseGet(object, path)
|
||||
if (predicate(value, path)) {
|
||||
baseSet(result, castPath(path, object), value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default basePickBy
|
||||
12
src/.internal/baseProperty.ts
Normal file
12
src/.internal/baseProperty.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* The base implementation of `property` without support for deep paths.
|
||||
*
|
||||
* @private
|
||||
* @param {string} key The key of the property to get.
|
||||
* @returns {Function} Returns the new accessor function.
|
||||
*/
|
||||
function baseProperty(key) {
|
||||
return (object) => object == null ? undefined : object[key]
|
||||
}
|
||||
|
||||
export default baseProperty
|
||||
14
src/.internal/basePropertyDeep.ts
Normal file
14
src/.internal/basePropertyDeep.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import baseGet from './baseGet.js'
|
||||
|
||||
/**
|
||||
* A specialized version of `baseProperty` which supports deep paths.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|string} path The path of the property to get.
|
||||
* @returns {Function} Returns the new accessor function.
|
||||
*/
|
||||
function basePropertyDeep(path) {
|
||||
return (object) => baseGet(object, path)
|
||||
}
|
||||
|
||||
export default basePropertyDeep
|
||||
12
src/.internal/basePropertyOf.ts
Normal file
12
src/.internal/basePropertyOf.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* The base implementation of `propertyOf` without support for deep paths.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to query.
|
||||
* @returns {Function} Returns the new accessor function.
|
||||
*/
|
||||
function basePropertyOf(object) {
|
||||
return (key) => object == null ? undefined : object[key]
|
||||
}
|
||||
|
||||
export default basePropertyOf
|
||||
44
src/.internal/basePullAll.ts
Normal file
44
src/.internal/basePullAll.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import map from '../map.js'
|
||||
import baseIndexOf from './baseIndexOf.js'
|
||||
import baseIndexOfWith from './baseIndexOfWith.js'
|
||||
import copyArray from './copyArray.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `pullAllBy`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to modify.
|
||||
* @param {Array} values The values to remove.
|
||||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||||
* @param {Function} [comparator] The comparator invoked per element.
|
||||
* @returns {Array} Returns `array`.
|
||||
*/
|
||||
function basePullAll(array, values, iteratee, comparator) {
|
||||
const indexOf = comparator ? baseIndexOfWith : baseIndexOf
|
||||
const length = values.length
|
||||
|
||||
let index = -1
|
||||
let seen = array
|
||||
|
||||
if (array === values) {
|
||||
values = copyArray(values)
|
||||
}
|
||||
if (iteratee) {
|
||||
seen = map(array, (value) => iteratee(value))
|
||||
}
|
||||
while (++index < length) {
|
||||
let fromIndex = 0
|
||||
const value = values[index]
|
||||
const computed = iteratee ? iteratee(value) : value
|
||||
|
||||
while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
|
||||
if (seen !== array) {
|
||||
seen.splice(fromIndex, 1)
|
||||
}
|
||||
array.splice(fromIndex, 1)
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
export default basePullAll
|
||||
32
src/.internal/basePullAt.ts
Normal file
32
src/.internal/basePullAt.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import baseUnset from './baseUnset.js'
|
||||
import isIndex from './isIndex.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `pullAt` without support for individual
|
||||
* indexes or capturing the removed elements.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to modify.
|
||||
* @param {number[]} indexes The indexes of elements to remove.
|
||||
* @returns {Array} Returns `array`.
|
||||
*/
|
||||
function basePullAt(array, indexes) {
|
||||
let length = array ? indexes.length : 0
|
||||
const lastIndex = length - 1
|
||||
|
||||
while (length--) {
|
||||
let previous
|
||||
const index = indexes[length]
|
||||
if (length === lastIndex || index !== previous) {
|
||||
previous = index
|
||||
if (isIndex(index)) {
|
||||
array.splice(index, 1)
|
||||
} else {
|
||||
baseUnset(array, index)
|
||||
}
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
export default basePullAt
|
||||
24
src/.internal/baseRange.ts
Normal file
24
src/.internal/baseRange.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* The base implementation of `range` and `rangeRight` which doesn't
|
||||
* coerce arguments.
|
||||
*
|
||||
* @private
|
||||
* @param {number} start The start of the range.
|
||||
* @param {number} end The end of the range.
|
||||
* @param {number} step The value to increment or decrement by.
|
||||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||||
* @returns {Array} Returns the range of numbers.
|
||||
*/
|
||||
function baseRange(start, end, step, fromRight) {
|
||||
let index = -1
|
||||
let length = Math.max(Math.ceil((end - start) / (step || 1)), 0)
|
||||
const result = new Array(length)
|
||||
|
||||
while (length--) {
|
||||
result[fromRight ? length : ++index] = start
|
||||
start += step
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseRange
|
||||
23
src/.internal/baseReduce.ts
Normal file
23
src/.internal/baseReduce.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* The base implementation of `reduce` and `reduceRight` which iterates
|
||||
* over `collection` using `eachFunc`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object} collection The collection to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @param {*} accumulator The initial value.
|
||||
* @param {boolean} initAccum Specify using the first or last element of
|
||||
* `collection` as the initial value.
|
||||
* @param {Function} eachFunc The function to iterate over `collection`.
|
||||
* @returns {*} Returns the accumulated value.
|
||||
*/
|
||||
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
|
||||
eachFunc(collection, (value, index, collection) => {
|
||||
accumulator = initAccum
|
||||
? (initAccum = false, value)
|
||||
: iteratee(accumulator, value, index, collection)
|
||||
})
|
||||
return accumulator
|
||||
}
|
||||
|
||||
export default baseReduce
|
||||
48
src/.internal/baseSet.ts
Normal file
48
src/.internal/baseSet.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import assignValue from './assignValue.js'
|
||||
import castPath from './castPath.js'
|
||||
import isIndex from './isIndex.js'
|
||||
import isObject from '../isObject.js'
|
||||
import toKey from './toKey.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `set`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to modify.
|
||||
* @param {Array|string} path The path of the property to set.
|
||||
* @param {*} value The value to set.
|
||||
* @param {Function} [customizer] The function to customize path creation.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function baseSet(object, path, value, customizer) {
|
||||
if (!isObject(object)) {
|
||||
return object
|
||||
}
|
||||
path = castPath(path, object)
|
||||
|
||||
const length = path.length
|
||||
const lastIndex = length - 1
|
||||
|
||||
let index = -1
|
||||
let nested = object
|
||||
|
||||
while (nested != null && ++index < length) {
|
||||
const key = toKey(path[index])
|
||||
let newValue = value
|
||||
|
||||
if (index != lastIndex) {
|
||||
const objValue = nested[key]
|
||||
newValue = customizer ? customizer(objValue, key, nested) : undefined
|
||||
if (newValue === undefined) {
|
||||
newValue = isObject(objValue)
|
||||
? objValue
|
||||
: (isIndex(path[index + 1]) ? [] : {})
|
||||
}
|
||||
}
|
||||
assignValue(nested, key, newValue)
|
||||
nested = nested[key]
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
||||
export default baseSet
|
||||
21
src/.internal/baseSortBy.ts
Normal file
21
src/.internal/baseSortBy.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* The base implementation of `sortBy` which uses `comparer` to define the
|
||||
* sort order of `array` and replaces criteria objects with their corresponding
|
||||
* values.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to sort.
|
||||
* @param {Function} comparer The function to define sort order.
|
||||
* @returns {Array} Returns `array`.
|
||||
*/
|
||||
function baseSortBy(array, comparer) {
|
||||
let { length } = array
|
||||
|
||||
array.sort(comparer)
|
||||
while (length--) {
|
||||
array[length] = array[length].value
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
export default baseSortBy
|
||||
40
src/.internal/baseSortedIndex.ts
Normal file
40
src/.internal/baseSortedIndex.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import baseSortedIndexBy from './baseSortedIndexBy.js'
|
||||
import isSymbol from '../isSymbol.js'
|
||||
|
||||
/** Used as references for the maximum length and index of an array. */
|
||||
const MAX_ARRAY_LENGTH = 4294967295
|
||||
const HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1
|
||||
|
||||
/**
|
||||
* The base implementation of `sortedIndex` and `sortedLastIndex` which
|
||||
* performs a binary search of `array` to determine the index at which `value`
|
||||
* should be inserted into `array` in order to maintain its sort order.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The sorted array to inspect.
|
||||
* @param {*} value The value to evaluate.
|
||||
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
||||
* @returns {number} Returns the index at which `value` should be inserted
|
||||
* into `array`.
|
||||
*/
|
||||
function baseSortedIndex(array, value, retHighest) {
|
||||
let low = 0
|
||||
let high = array == null ? low : array.length
|
||||
|
||||
if (typeof value === 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
|
||||
while (low < high) {
|
||||
const mid = (low + high) >>> 1
|
||||
const computed = array[mid]
|
||||
if (computed !== null && !isSymbol(computed) &&
|
||||
(retHighest ? (computed <= value) : (computed < value))) {
|
||||
low = mid + 1
|
||||
} else {
|
||||
high = mid
|
||||
}
|
||||
}
|
||||
return high
|
||||
}
|
||||
return baseSortedIndexBy(array, value, (value) => value, retHighest)
|
||||
}
|
||||
|
||||
export default baseSortedIndex
|
||||
65
src/.internal/baseSortedIndexBy.ts
Normal file
65
src/.internal/baseSortedIndexBy.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import isSymbol from '../isSymbol.js'
|
||||
|
||||
/** Used as references for the maximum length and index of an array. */
|
||||
const MAX_ARRAY_LENGTH = 4294967295
|
||||
const MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1
|
||||
|
||||
/**
|
||||
* The base implementation of `sortedIndexBy` and `sortedLastIndexBy`
|
||||
* which invokes `iteratee` for `value` and each element of `array` to compute
|
||||
* their sort ranking. The iteratee is invoked with one argument (value).
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The sorted array to inspect.
|
||||
* @param {*} value The value to evaluate.
|
||||
* @param {Function} iteratee The iteratee invoked per element.
|
||||
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
||||
* @returns {number} Returns the index at which `value` should be inserted
|
||||
* into `array`.
|
||||
*/
|
||||
function baseSortedIndexBy(array, value, iteratee, retHighest) {
|
||||
let low = 0
|
||||
let high = array == null ? 0 : array.length
|
||||
if (high == 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
value = iteratee(value)
|
||||
|
||||
const valIsNaN = value !== value
|
||||
const valIsNull = value === null
|
||||
const valIsSymbol = isSymbol(value)
|
||||
const valIsUndefined = value === undefined
|
||||
|
||||
while (low < high) {
|
||||
let setLow
|
||||
const mid = Math.floor((low + high) / 2)
|
||||
const computed = iteratee(array[mid])
|
||||
const othIsDefined = computed !== undefined
|
||||
const othIsNull = computed === null
|
||||
const othIsReflexive = computed === computed
|
||||
const othIsSymbol = isSymbol(computed)
|
||||
|
||||
if (valIsNaN) {
|
||||
setLow = retHighest || othIsReflexive
|
||||
} else if (valIsUndefined) {
|
||||
setLow = othIsReflexive && (retHighest || othIsDefined)
|
||||
} else if (valIsNull) {
|
||||
setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull)
|
||||
} else if (valIsSymbol) {
|
||||
setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol)
|
||||
} else if (othIsNull || othIsSymbol) {
|
||||
setLow = false
|
||||
} else {
|
||||
setLow = retHighest ? (computed <= value) : (computed < value)
|
||||
}
|
||||
if (setLow) {
|
||||
low = mid + 1
|
||||
} else {
|
||||
high = mid
|
||||
}
|
||||
}
|
||||
return Math.min(high, MAX_ARRAY_INDEX)
|
||||
}
|
||||
|
||||
export default baseSortedIndexBy
|
||||
29
src/.internal/baseSortedUniq.ts
Normal file
29
src/.internal/baseSortedUniq.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import eq from '../eq.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `sortedUniq` and `sortedUniqBy`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||||
* @returns {Array} Returns the new duplicate free array.
|
||||
*/
|
||||
function baseSortedUniq(array, iteratee) {
|
||||
let seen
|
||||
let index = -1
|
||||
let resIndex = 0
|
||||
|
||||
const { length } = array
|
||||
const result = []
|
||||
|
||||
while (++index < length) {
|
||||
const value = array[index], computed = iteratee ? iteratee(value) : value
|
||||
if (!index || !eq(computed, seen)) {
|
||||
seen = computed
|
||||
result[resIndex++] = value === 0 ? 0 : value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseSortedUniq
|
||||
21
src/.internal/baseSum.ts
Normal file
21
src/.internal/baseSum.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* The base implementation of `sum` and `sumBy`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} iteratee The function invoked per iteration.
|
||||
* @returns {number} Returns the sum.
|
||||
*/
|
||||
function baseSum(array, iteratee) {
|
||||
let result
|
||||
|
||||
for (const value of array) {
|
||||
const current = iteratee(value)
|
||||
if (current !== undefined) {
|
||||
result = result === undefined ? current : (result + current)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseSum
|
||||
24
src/.internal/baseToNumber.ts
Normal file
24
src/.internal/baseToNumber.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import isSymbol from '../isSymbol.js'
|
||||
|
||||
/** Used as references for various `Number` constants. */
|
||||
const NAN = 0 / 0
|
||||
|
||||
/**
|
||||
* The base implementation of `toNumber` which doesn't ensure correct
|
||||
* conversions of binary, hexadecimal, or octal string values.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to process.
|
||||
* @returns {number} Returns the number.
|
||||
*/
|
||||
function baseToNumber(value) {
|
||||
if (typeof value === 'number') {
|
||||
return value
|
||||
}
|
||||
if (isSymbol(value)) {
|
||||
return NAN
|
||||
}
|
||||
return +value
|
||||
}
|
||||
|
||||
export default baseToNumber
|
||||
33
src/.internal/baseToString.ts
Normal file
33
src/.internal/baseToString.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import isSymbol from '../isSymbol.js'
|
||||
|
||||
/** Used as references for various `Number` constants. */
|
||||
const INFINITY = 1 / 0
|
||||
|
||||
/** Used to convert symbols to primitives and strings. */
|
||||
const symbolToString = Symbol.prototype.toString
|
||||
|
||||
/**
|
||||
* The base implementation of `toString` which doesn't convert nullish
|
||||
* values to empty strings.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to process.
|
||||
* @returns {string} Returns the string.
|
||||
*/
|
||||
function baseToString(value) {
|
||||
// Exit early for strings to avoid a performance hit in some environments.
|
||||
if (typeof value === 'string') {
|
||||
return value
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
// Recursively convert values (susceptible to call stack limits).
|
||||
return `${value.map(baseToString)}`
|
||||
}
|
||||
if (isSymbol(value)) {
|
||||
return symbolToString ? symbolToString.call(value) : ''
|
||||
}
|
||||
const result = `${value}`
|
||||
return (result === '0' && (1 / value) === -INFINITY) ? '-0' : result
|
||||
}
|
||||
|
||||
export default baseToString
|
||||
73
src/.internal/baseUniq.ts
Normal file
73
src/.internal/baseUniq.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import SetCache from './SetCache.js'
|
||||
import arrayIncludes from './arrayIncludes.js'
|
||||
import arrayIncludesWith from './arrayIncludesWith.js'
|
||||
import cacheHas from './cacheHas.js'
|
||||
import createSet from './createSet.js'
|
||||
import setToArray from './setToArray.js'
|
||||
|
||||
/** Used as the size to enable large array optimizations. */
|
||||
const LARGE_ARRAY_SIZE = 200
|
||||
|
||||
/**
|
||||
* The base implementation of `uniqBy`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||||
* @param {Function} [comparator] The comparator invoked per element.
|
||||
* @returns {Array} Returns the new duplicate free array.
|
||||
*/
|
||||
function baseUniq(array, iteratee, comparator) {
|
||||
let index = -1
|
||||
let includes = arrayIncludes
|
||||
let isCommon = true
|
||||
|
||||
const { length } = array
|
||||
const result = []
|
||||
let seen = result
|
||||
|
||||
if (comparator) {
|
||||
isCommon = false
|
||||
includes = arrayIncludesWith
|
||||
}
|
||||
else if (length >= LARGE_ARRAY_SIZE) {
|
||||
const set = iteratee ? null : createSet(array)
|
||||
if (set) {
|
||||
return setToArray(set)
|
||||
}
|
||||
isCommon = false
|
||||
includes = cacheHas
|
||||
seen = new SetCache
|
||||
}
|
||||
else {
|
||||
seen = iteratee ? [] : result
|
||||
}
|
||||
outer:
|
||||
while (++index < length) {
|
||||
let value = array[index]
|
||||
const computed = iteratee ? iteratee(value) : value
|
||||
|
||||
value = (comparator || value !== 0) ? value : 0
|
||||
if (isCommon && computed === computed) {
|
||||
let seenIndex = seen.length
|
||||
while (seenIndex--) {
|
||||
if (seen[seenIndex] === computed) {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
if (iteratee) {
|
||||
seen.push(computed)
|
||||
}
|
||||
result.push(value)
|
||||
}
|
||||
else if (!includes(seen, computed, comparator)) {
|
||||
if (seen !== result) {
|
||||
seen.push(computed)
|
||||
}
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseUniq
|
||||
20
src/.internal/baseUnset.ts
Normal file
20
src/.internal/baseUnset.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import castPath from './castPath.js'
|
||||
import last from '../last.js'
|
||||
import parent from './parent.js'
|
||||
import toKey from './toKey.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `unset`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to modify.
|
||||
* @param {Array|string} path The property path to unset.
|
||||
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
|
||||
*/
|
||||
function baseUnset(object, path) {
|
||||
path = castPath(path, object)
|
||||
object = parent(object, path)
|
||||
return object == null || delete object[toKey(last(path))]
|
||||
}
|
||||
|
||||
export default baseUnset
|
||||
18
src/.internal/baseUpdate.ts
Normal file
18
src/.internal/baseUpdate.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import baseGet from './baseGet.js'
|
||||
import baseSet from './baseSet.js'
|
||||
|
||||
/**
|
||||
* The base implementation of `update`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to modify.
|
||||
* @param {Array|string} path The path of the property to update.
|
||||
* @param {Function} updater The function to produce the updated value.
|
||||
* @param {Function} [customizer] The function to customize path creation.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function baseUpdate(object, path, updater, customizer) {
|
||||
return baseSet(object, path, updater(baseGet(object, path)), customizer)
|
||||
}
|
||||
|
||||
export default baseUpdate
|
||||
15
src/.internal/baseValues.ts
Normal file
15
src/.internal/baseValues.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* The base implementation of `values` and `valuesIn` which creates an
|
||||
* array of `object` property values corresponding to the property names
|
||||
* of `props`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to query.
|
||||
* @param {Array} props The property names to get values for.
|
||||
* @returns {Object} Returns the array of property values.
|
||||
*/
|
||||
function baseValues(object, props) {
|
||||
return props == null ? [] : props.map((key) => object[key])
|
||||
}
|
||||
|
||||
export default baseValues
|
||||
25
src/.internal/baseWhile.ts
Normal file
25
src/.internal/baseWhile.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import slice from '../slice.js'
|
||||
|
||||
/**
|
||||
* The base implementation of methods like `dropWhile` and `takeWhile`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to query.
|
||||
* @param {Function} predicate The function invoked per iteration.
|
||||
* @param {boolean} [isDrop] Specify dropping elements instead of taking them.
|
||||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||||
* @returns {Array} Returns the slice of `array`.
|
||||
*/
|
||||
function baseWhile(array, predicate, isDrop, fromRight) {
|
||||
const { length } = array
|
||||
let index = fromRight ? length : -1
|
||||
|
||||
while ((fromRight ? index-- : ++index < length) &&
|
||||
predicate(array[index], index, array)) {}
|
||||
|
||||
return isDrop
|
||||
? slice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
|
||||
: slice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index))
|
||||
}
|
||||
|
||||
export default baseWhile
|
||||
36
src/.internal/baseXor.ts
Normal file
36
src/.internal/baseXor.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import baseDifference from './baseDifference.js'
|
||||
import baseFlatten from './baseFlatten.js'
|
||||
import baseUniq from './baseUniq.js'
|
||||
|
||||
/**
|
||||
* The base implementation of methods like `xor` which accepts an array of
|
||||
* arrays to inspect.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} arrays The arrays to inspect.
|
||||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||||
* @param {Function} [comparator] The comparator invoked per element.
|
||||
* @returns {Array} Returns the new array of values.
|
||||
*/
|
||||
function baseXor(arrays, iteratee, comparator) {
|
||||
const length = arrays.length
|
||||
if (length < 2) {
|
||||
return length ? baseUniq(arrays[0]) : []
|
||||
}
|
||||
let index = -1
|
||||
const result = new Array(length)
|
||||
|
||||
while (++index < length) {
|
||||
const array = arrays[index]
|
||||
let othIndex = -1
|
||||
|
||||
while (++othIndex < length) {
|
||||
if (othIndex != index) {
|
||||
result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator)
|
||||
}
|
||||
}
|
||||
}
|
||||
return baseUniq(baseFlatten(result, 1), iteratee, comparator)
|
||||
}
|
||||
|
||||
export default baseXor
|
||||
23
src/.internal/baseZipObject.ts
Normal file
23
src/.internal/baseZipObject.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* This base implementation of `zipObject` which assigns values using `assignFunc`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} props The property identifiers.
|
||||
* @param {Array} values The property values.
|
||||
* @param {Function} assignFunc The function to assign values.
|
||||
* @returns {Object} Returns the new object.
|
||||
*/
|
||||
function baseZipObject(props, values, assignFunc) {
|
||||
let index = -1
|
||||
const length = props.length
|
||||
const valsLength = values.length
|
||||
const result = {}
|
||||
|
||||
while (++index < length) {
|
||||
const value = index < valsLength ? values[index] : undefined
|
||||
assignFunc(result, props[index], value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default baseZipObject
|
||||
13
src/.internal/cacheHas.ts
Normal file
13
src/.internal/cacheHas.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Checks if a `cache` value for `key` exists.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} cache The cache to query.
|
||||
* @param {string} key The key of the entry to check.
|
||||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||||
*/
|
||||
function cacheHas(cache, key) {
|
||||
return cache.has(key)
|
||||
}
|
||||
|
||||
export default cacheHas
|
||||
14
src/.internal/castArrayLikeObject.ts
Normal file
14
src/.internal/castArrayLikeObject.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import isArrayLikeObject from '../isArrayLikeObject.js'
|
||||
|
||||
/**
|
||||
* Casts `value` to an empty array if it's not an array like object.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to inspect.
|
||||
* @returns {Array|Object} Returns the cast array-like object.
|
||||
*/
|
||||
function castArrayLikeObject(value) {
|
||||
return isArrayLikeObject(value) ? value : []
|
||||
}
|
||||
|
||||
export default castArrayLikeObject
|
||||
19
src/.internal/castPath.ts
Normal file
19
src/.internal/castPath.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import isKey from './isKey.js'
|
||||
import stringToPath from './stringToPath.js'
|
||||
|
||||
/**
|
||||
* Casts `value` to a path array if it's not one.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to inspect.
|
||||
* @param {Object} [object] The object to query keys on.
|
||||
* @returns {Array} Returns the cast property path array.
|
||||
*/
|
||||
function castPath(value, object) {
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
return isKey(value, object) ? [value] : stringToPath(value)
|
||||
}
|
||||
|
||||
export default castPath
|
||||
18
src/.internal/castSlice.ts
Normal file
18
src/.internal/castSlice.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import slice from '../slice.js'
|
||||
|
||||
/**
|
||||
* Casts `array` to a slice if it's needed.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to inspect.
|
||||
* @param {number} start The start position.
|
||||
* @param {number} [end=array.length] The end position.
|
||||
* @returns {Array} Returns the cast slice.
|
||||
*/
|
||||
function castSlice(array, start, end) {
|
||||
const { length } = array
|
||||
end = end === undefined ? length : end
|
||||
return (!start && end >= length) ? array : slice(array, start, end)
|
||||
}
|
||||
|
||||
export default castSlice
|
||||
19
src/.internal/charsEndIndex.ts
Normal file
19
src/.internal/charsEndIndex.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import baseIndexOf from './baseIndexOf.js'
|
||||
|
||||
/**
|
||||
* Used by `trim` and `trimEnd` to get the index of the last string symbol
|
||||
* that is not found in the character symbols.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} strSymbols The string symbols to inspect.
|
||||
* @param {Array} chrSymbols The character symbols to find.
|
||||
* @returns {number} Returns the index of the last unmatched string symbol.
|
||||
*/
|
||||
function charsEndIndex(strSymbols, chrSymbols) {
|
||||
let index = strSymbols.length
|
||||
|
||||
while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
||||
return index
|
||||
}
|
||||
|
||||
export default charsEndIndex
|
||||
20
src/.internal/charsStartIndex.ts
Normal file
20
src/.internal/charsStartIndex.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import baseIndexOf from './baseIndexOf.js'
|
||||
|
||||
/**
|
||||
* Used by `trim` and `trimStart` to get the index of the first string symbol
|
||||
* that is not found in the character symbols.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} strSymbols The string symbols to inspect.
|
||||
* @param {Array} chrSymbols The character symbols to find.
|
||||
* @returns {number} Returns the index of the first unmatched string symbol.
|
||||
*/
|
||||
function charsStartIndex(strSymbols, chrSymbols) {
|
||||
let index = -1
|
||||
const length = strSymbols.length
|
||||
|
||||
while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
||||
return index
|
||||
}
|
||||
|
||||
export default charsStartIndex
|
||||
14
src/.internal/cloneArrayBuffer.ts
Normal file
14
src/.internal/cloneArrayBuffer.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Creates a clone of `arrayBuffer`.
|
||||
*
|
||||
* @private
|
||||
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
||||
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
||||
*/
|
||||
function cloneArrayBuffer(arrayBuffer) {
|
||||
const result = new arrayBuffer.constructor(arrayBuffer.byteLength)
|
||||
new Uint8Array(result).set(new Uint8Array(arrayBuffer))
|
||||
return result
|
||||
}
|
||||
|
||||
export default cloneArrayBuffer
|
||||
34
src/.internal/cloneBuffer.ts
Normal file
34
src/.internal/cloneBuffer.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import root from './root.js'
|
||||
|
||||
/** Detect free variable `exports`. */
|
||||
const freeExports = typeof exports === 'object' && exports !== null && !exports.nodeType && exports
|
||||
|
||||
/** Detect free variable `module`. */
|
||||
const freeModule = freeExports && typeof module === 'object' && module !== null && !module.nodeType && module
|
||||
|
||||
/** Detect the popular CommonJS extension `module.exports`. */
|
||||
const moduleExports = freeModule && freeModule.exports === freeExports
|
||||
|
||||
/** Built-in value references. */
|
||||
const Buffer = moduleExports ? root.Buffer : undefined, allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined
|
||||
|
||||
/**
|
||||
* Creates a clone of `buffer`.
|
||||
*
|
||||
* @private
|
||||
* @param {Buffer} buffer The buffer to clone.
|
||||
* @param {boolean} [isDeep] Specify a deep clone.
|
||||
* @returns {Buffer} Returns the cloned buffer.
|
||||
*/
|
||||
function cloneBuffer(buffer, isDeep) {
|
||||
if (isDeep) {
|
||||
return buffer.slice()
|
||||
}
|
||||
const length = buffer.length
|
||||
const result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length)
|
||||
|
||||
buffer.copy(result)
|
||||
return result
|
||||
}
|
||||
|
||||
export default cloneBuffer
|
||||
16
src/.internal/cloneDataView.ts
Normal file
16
src/.internal/cloneDataView.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import cloneArrayBuffer from './cloneArrayBuffer.js'
|
||||
|
||||
/**
|
||||
* Creates a clone of `dataView`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} dataView The data view to clone.
|
||||
* @param {boolean} [isDeep] Specify a deep clone.
|
||||
* @returns {Object} Returns the cloned data view.
|
||||
*/
|
||||
function cloneDataView(dataView, isDeep) {
|
||||
const buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer
|
||||
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength)
|
||||
}
|
||||
|
||||
export default cloneDataView
|
||||
17
src/.internal/cloneRegExp.ts
Normal file
17
src/.internal/cloneRegExp.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/** Used to match `RegExp` flags from their coerced string values. */
|
||||
const reFlags = /\w*$/
|
||||
|
||||
/**
|
||||
* Creates a clone of `regexp`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} regexp The regexp to clone.
|
||||
* @returns {Object} Returns the cloned regexp.
|
||||
*/
|
||||
function cloneRegExp(regexp) {
|
||||
const result = new regexp.constructor(regexp.source, reFlags.exec(regexp))
|
||||
result.lastIndex = regexp.lastIndex
|
||||
return result
|
||||
}
|
||||
|
||||
export default cloneRegExp
|
||||
15
src/.internal/cloneSymbol.ts
Normal file
15
src/.internal/cloneSymbol.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/** Used to convert symbols to primitives and strings. */
|
||||
const symbolValueOf = Symbol.prototype.valueOf
|
||||
|
||||
/**
|
||||
* Creates a clone of the `symbol` object.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} symbol The symbol object to clone.
|
||||
* @returns {Object} Returns the cloned symbol object.
|
||||
*/
|
||||
function cloneSymbol(symbol) {
|
||||
return Object(symbolValueOf.call(symbol))
|
||||
}
|
||||
|
||||
export default cloneSymbol
|
||||
16
src/.internal/cloneTypedArray.ts
Normal file
16
src/.internal/cloneTypedArray.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import cloneArrayBuffer from './cloneArrayBuffer.js'
|
||||
|
||||
/**
|
||||
* Creates a clone of `typedArray`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} typedArray The typed array to clone.
|
||||
* @param {boolean} [isDeep] Specify a deep clone.
|
||||
* @returns {Object} Returns the cloned typed array.
|
||||
*/
|
||||
function cloneTypedArray(typedArray, isDeep) {
|
||||
const buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer
|
||||
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length)
|
||||
}
|
||||
|
||||
export default cloneTypedArray
|
||||
45
src/.internal/compareAscending.ts
Normal file
45
src/.internal/compareAscending.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import isSymbol from '../isSymbol.js'
|
||||
|
||||
/**
|
||||
* Compares values to sort them in ascending order.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to compare.
|
||||
* @param {*} other The other value to compare.
|
||||
* @returns {number} Returns the sort order indicator for `value`.
|
||||
*/
|
||||
function compareAscending(value, other) {
|
||||
if (value !== other) {
|
||||
const valIsDefined = value !== undefined
|
||||
const valIsNull = value === null
|
||||
const valIsReflexive = value === value
|
||||
const valIsSymbol = isSymbol(value)
|
||||
|
||||
const othIsDefined = other !== undefined
|
||||
const othIsNull = other === null
|
||||
const othIsReflexive = other === other
|
||||
const othIsSymbol = isSymbol(other)
|
||||
|
||||
const val = typeof value === 'string'
|
||||
? value.localeCompare(other)
|
||||
: -other
|
||||
|
||||
if ((!othIsNull && !othIsSymbol && !valIsSymbol && val > 0) ||
|
||||
(valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
|
||||
(valIsNull && othIsDefined && othIsReflexive) ||
|
||||
(!valIsDefined && othIsReflexive) ||
|
||||
!valIsReflexive) {
|
||||
return 1
|
||||
}
|
||||
if ((!valIsNull && !valIsSymbol && !othIsSymbol && val < 0) ||
|
||||
(othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
|
||||
(othIsNull && valIsDefined && valIsReflexive) ||
|
||||
(!othIsDefined && valIsReflexive) ||
|
||||
!othIsReflexive) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
export default compareAscending
|
||||
45
src/.internal/compareMultiple.ts
Normal file
45
src/.internal/compareMultiple.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import compareAscending from './compareAscending.js'
|
||||
|
||||
/**
|
||||
* Used by `orderBy` to compare multiple properties of a value to another
|
||||
* and stable sort them.
|
||||
*
|
||||
* If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
|
||||
* specify an order of "desc" for descending or "asc" for ascending sort order
|
||||
* of corresponding values.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to compare.
|
||||
* @param {Object} other The other object to compare.
|
||||
* @param {(string|function)[]} orders The order to sort by for each property.
|
||||
* @returns {number} Returns the sort order indicator for `object`.
|
||||
*/
|
||||
function compareMultiple(object, other, orders) {
|
||||
let index = -1
|
||||
const objCriteria = object.criteria
|
||||
const othCriteria = other.criteria
|
||||
const length = objCriteria.length
|
||||
const ordersLength = orders.length
|
||||
|
||||
while (++index < length) {
|
||||
const order = index < ordersLength ? orders[index] : null
|
||||
const cmpFn = (order && typeof order === 'function') ? order: compareAscending
|
||||
const result = cmpFn(objCriteria[index], othCriteria[index])
|
||||
if (result) {
|
||||
if (order && typeof order !== 'function') {
|
||||
return result * (order == 'desc' ? -1 : 1)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
|
||||
// that causes it, under certain circumstances, to provide the same value for
|
||||
// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
|
||||
// for more details.
|
||||
//
|
||||
// This also ensures a stable sort in V8 and other engines.
|
||||
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
|
||||
return object.index - other.index
|
||||
}
|
||||
|
||||
export default compareMultiple
|
||||
38
src/.internal/composeArgs.ts
Normal file
38
src/.internal/composeArgs.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Creates an array that is the composition of partially applied arguments,
|
||||
* placeholders, and provided arguments into a single array of arguments.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} args The provided arguments.
|
||||
* @param {Array} partials The arguments to prepend to those provided.
|
||||
* @param {Array} holders The `partials` placeholder indexes.
|
||||
* @params {boolean} [isCurried] Specify composing for a curried function.
|
||||
* @returns {Array} Returns the new array of composed arguments.
|
||||
*/
|
||||
function composeArgs(args, partials, holders, isCurried) {
|
||||
const argsLength = args.length
|
||||
const holdersLength = holders.length
|
||||
const leftLength = partials.length
|
||||
|
||||
let argsIndex = -1
|
||||
let leftIndex = -1
|
||||
let rangeLength = Math.max(argsLength - holdersLength, 0)
|
||||
|
||||
const result = new Array(leftLength + rangeLength)
|
||||
const isUncurried = !isCurried
|
||||
|
||||
while (++leftIndex < leftLength) {
|
||||
result[leftIndex] = partials[leftIndex]
|
||||
}
|
||||
while (++argsIndex < holdersLength) {
|
||||
if (isUncurried || argsIndex < argsLength) {
|
||||
result[holders[argsIndex]] = args[argsIndex]
|
||||
}
|
||||
}
|
||||
while (rangeLength--) {
|
||||
result[leftIndex++] = args[argsIndex++]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default composeArgs
|
||||
39
src/.internal/composeArgsRight.ts
Normal file
39
src/.internal/composeArgsRight.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* This function is like `composeArgs` except that the arguments composition
|
||||
* is tailored for `partialRight`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} args The provided arguments.
|
||||
* @param {Array} partials The arguments to append to those provided.
|
||||
* @param {Array} holders The `partials` placeholder indexes.
|
||||
* @params {boolean} [isCurried] Specify composing for a curried function.
|
||||
* @returns {Array} Returns the new array of composed arguments.
|
||||
*/
|
||||
function composeArgsRight(args, partials, holders, isCurried) {
|
||||
let argsIndex = -1
|
||||
let holdersIndex = -1
|
||||
let rightIndex = -1
|
||||
|
||||
const argsLength = args.length
|
||||
const holdersLength = holders.length
|
||||
const rightLength = partials.length
|
||||
const rangeLength = Math.max(argsLength - holdersLength, 0)
|
||||
const result = new Array(rangeLength + rightLength)
|
||||
const isUncurried = !isCurried
|
||||
|
||||
while (++argsIndex < rangeLength) {
|
||||
result[argsIndex] = args[argsIndex]
|
||||
}
|
||||
const offset = argsIndex
|
||||
while (++rightIndex < rightLength) {
|
||||
result[offset + rightIndex] = partials[rightIndex]
|
||||
}
|
||||
while (++holdersIndex < holdersLength) {
|
||||
if (isUncurried || argsIndex < argsLength) {
|
||||
result[offset + holders[holdersIndex]] = args[argsIndex++]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default composeArgsRight
|
||||
20
src/.internal/copyArray.ts
Normal file
20
src/.internal/copyArray.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copies the values of `source` to `array`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} source The array to copy values from.
|
||||
* @param {Array} [array=[]] The array to copy values to.
|
||||
* @returns {Array} Returns `array`.
|
||||
*/
|
||||
function copyArray(source, array) {
|
||||
let index = -1
|
||||
const length = source.length
|
||||
|
||||
array || (array = new Array(length))
|
||||
while (++index < length) {
|
||||
array[index] = source[index]
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
export default copyArray
|
||||
35
src/.internal/copyObject.ts
Normal file
35
src/.internal/copyObject.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import assignValue from './assignValue.js'
|
||||
import baseAssignValue from './baseAssignValue.js'
|
||||
|
||||
/**
|
||||
* Copies properties of `source` to `object`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} source The object to copy properties from.
|
||||
* @param {Array} props The property identifiers to copy.
|
||||
* @param {Object} [object={}] The object to copy properties to.
|
||||
* @param {Function} [customizer] The function to customize copied values.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function copyObject(source, props, object, customizer) {
|
||||
const isNew = !object
|
||||
object || (object = {})
|
||||
|
||||
for (const key of props) {
|
||||
let newValue = customizer
|
||||
? customizer(object[key], source[key], key, object, source)
|
||||
: undefined
|
||||
|
||||
if (newValue === undefined) {
|
||||
newValue = source[key]
|
||||
}
|
||||
if (isNew) {
|
||||
baseAssignValue(object, key, newValue)
|
||||
} else {
|
||||
assignValue(object, key, newValue)
|
||||
}
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
||||
export default copyObject
|
||||
16
src/.internal/copySymbols.ts
Normal file
16
src/.internal/copySymbols.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import copyObject from './copyObject.js'
|
||||
import getSymbols from './getSymbols.js'
|
||||
|
||||
/**
|
||||
* Copies own symbols of `source` to `object`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} source The object to copy symbols from.
|
||||
* @param {Object} [object={}] The object to copy symbols to.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function copySymbols(source, object) {
|
||||
return copyObject(source, getSymbols(source), object)
|
||||
}
|
||||
|
||||
export default copySymbols
|
||||
16
src/.internal/copySymbolsIn.ts
Normal file
16
src/.internal/copySymbolsIn.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import copyObject from './copyObject.js'
|
||||
import getSymbolsIn from './getSymbolsIn.js'
|
||||
|
||||
/**
|
||||
* Copies own and inherited symbols of `source` to `object`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} source The object to copy symbols from.
|
||||
* @param {Object} [object={}] The object to copy symbols to.
|
||||
* @returns {Object} Returns `object`.
|
||||
*/
|
||||
function copySymbolsIn(source, object) {
|
||||
return copyObject(source, getSymbolsIn(source), object)
|
||||
}
|
||||
|
||||
export default copySymbolsIn
|
||||
36
src/.internal/createAssigner.ts
Normal file
36
src/.internal/createAssigner.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import isIterateeCall from './isIterateeCall.js'
|
||||
|
||||
/**
|
||||
* Creates a function like `assign`.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} assigner The function to assign values.
|
||||
* @returns {Function} Returns the new assigner function.
|
||||
*/
|
||||
function createAssigner(assigner) {
|
||||
return (object, ...sources) => {
|
||||
let index = -1
|
||||
let length = sources.length
|
||||
let customizer = length > 1 ? sources[length - 1] : undefined
|
||||
const guard = length > 2 ? sources[2] : undefined
|
||||
|
||||
customizer = (assigner.length > 3 && typeof customizer === 'function')
|
||||
? (length--, customizer)
|
||||
: undefined
|
||||
|
||||
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
||||
customizer = length < 3 ? undefined : customizer
|
||||
length = 1
|
||||
}
|
||||
object = Object(object)
|
||||
while (++index < length) {
|
||||
const source = sources[index]
|
||||
if (source) {
|
||||
assigner(object, source, index, customizer)
|
||||
}
|
||||
}
|
||||
return object
|
||||
}
|
||||
}
|
||||
|
||||
export default createAssigner
|
||||
34
src/.internal/createCaseFirst.ts
Normal file
34
src/.internal/createCaseFirst.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import castSlice from './castSlice.js'
|
||||
import hasUnicode from './hasUnicode.js'
|
||||
import stringToArray from './stringToArray.js'
|
||||
|
||||
/**
|
||||
* Creates a function like `lowerFirst`.
|
||||
*
|
||||
* @private
|
||||
* @param {string} methodName The name of the `String` case method to use.
|
||||
* @returns {Function} Returns the new case function.
|
||||
*/
|
||||
function createCaseFirst(methodName) {
|
||||
return (string) => {
|
||||
if (!string) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const strSymbols = hasUnicode(string)
|
||||
? stringToArray(string)
|
||||
: undefined
|
||||
|
||||
const chr = strSymbols
|
||||
? strSymbols[0]
|
||||
: string[0]
|
||||
|
||||
const trailing = strSymbols
|
||||
? castSlice(strSymbols, 1).join('')
|
||||
: string.slice(1)
|
||||
|
||||
return chr[methodName]() + trailing
|
||||
}
|
||||
}
|
||||
|
||||
export default createCaseFirst
|
||||
35
src/.internal/createMathOperation.ts
Normal file
35
src/.internal/createMathOperation.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import baseToNumber from './baseToNumber.js'
|
||||
import baseToString from './baseToString.js'
|
||||
|
||||
/**
|
||||
* Creates a function that performs a mathematical operation on two values.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} operator The function to perform the operation.
|
||||
* @param {number} [defaultValue] The value used for `undefined` arguments.
|
||||
* @returns {Function} Returns the new mathematical operation function.
|
||||
*/
|
||||
function createMathOperation(operator, defaultValue) {
|
||||
return (value, other) => {
|
||||
if (value === undefined && other === undefined) {
|
||||
return defaultValue
|
||||
}
|
||||
if (value !== undefined && other === undefined) {
|
||||
return value
|
||||
}
|
||||
if (other !== undefined && value === undefined) {
|
||||
return other
|
||||
}
|
||||
if (typeof value === 'string' || typeof other === 'string') {
|
||||
value = baseToString(value)
|
||||
other = baseToString(other)
|
||||
}
|
||||
else {
|
||||
value = baseToNumber(value)
|
||||
other = baseToNumber(other)
|
||||
}
|
||||
return operator(value, other)
|
||||
}
|
||||
}
|
||||
|
||||
export default createMathOperation
|
||||
30
src/.internal/createPadding.ts
Normal file
30
src/.internal/createPadding.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import repeat from '../repeat.js'
|
||||
import baseToString from './baseToString.js'
|
||||
import castSlice from './castSlice.js'
|
||||
import hasUnicode from './hasUnicode.js'
|
||||
import stringSize from './stringSize.js'
|
||||
import stringToArray from './stringToArray.js'
|
||||
|
||||
/**
|
||||
* Creates the padding for `string` based on `length`. The `chars` string
|
||||
* is truncated if the number of characters exceeds `length`.
|
||||
*
|
||||
* @private
|
||||
* @param {number} length The padding length.
|
||||
* @param {string} [chars=' '] The string used as padding.
|
||||
* @returns {string} Returns the padding for `string`.
|
||||
*/
|
||||
function createPadding(length, chars) {
|
||||
chars = chars === undefined ? ' ' : baseToString(chars)
|
||||
|
||||
const charsLength = chars.length
|
||||
if (charsLength < 2) {
|
||||
return charsLength ? repeat(chars, length) : chars
|
||||
}
|
||||
const result = repeat(chars, Math.ceil(length / stringSize(chars)))
|
||||
return hasUnicode(chars)
|
||||
? castSlice(stringToArray(result), 0, length).join('')
|
||||
: result.slice(0, length)
|
||||
}
|
||||
|
||||
export default createPadding
|
||||
26
src/.internal/createRange.ts
Normal file
26
src/.internal/createRange.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import baseRange from './baseRange.js'
|
||||
import toFinite from '../toFinite.js'
|
||||
|
||||
/**
|
||||
* Creates a `range` or `rangeRight` function.
|
||||
*
|
||||
* @private
|
||||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||||
* @returns {Function} Returns the new range function.
|
||||
*/
|
||||
function createRange(fromRight) {
|
||||
return (start, end, step) => {
|
||||
// Ensure the sign of `-0` is preserved.
|
||||
start = toFinite(start)
|
||||
if (end === undefined) {
|
||||
end = start
|
||||
start = 0
|
||||
} else {
|
||||
end = toFinite(end)
|
||||
}
|
||||
step = step === undefined ? (start < end ? 1 : -1) : toFinite(step)
|
||||
return baseRange(start, end, step, fromRight)
|
||||
}
|
||||
}
|
||||
|
||||
export default createRange
|
||||
25
src/.internal/createRound.ts
Normal file
25
src/.internal/createRound.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Creates a function like `round`.
|
||||
*
|
||||
* @private
|
||||
* @param {string} methodName The name of the `Math` method to use when rounding.
|
||||
* @returns {Function} Returns the new round function.
|
||||
*/
|
||||
function createRound(methodName) {
|
||||
const func = Math[methodName]
|
||||
return (number, precision) => {
|
||||
precision = precision == null ? 0 : (precision >= 0 ? Math.min(precision, 292) : Math.max(precision, -292))
|
||||
if (precision) {
|
||||
// Shift with exponential notation to avoid floating-point issues.
|
||||
// See [MDN](https://mdn.io/round#Examples) for more details.
|
||||
let pair = `${number}e`.split('e')
|
||||
const value = func(`${pair[0]}e${+pair[1] + precision}`)
|
||||
|
||||
pair = `${value}e`.split('e')
|
||||
return +`${pair[0]}e${+pair[1] - precision}`
|
||||
}
|
||||
return func(number)
|
||||
}
|
||||
}
|
||||
|
||||
export default createRound
|
||||
17
src/.internal/createSet.ts
Normal file
17
src/.internal/createSet.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import setToArray from './setToArray.js'
|
||||
|
||||
/** Used as references for various `Number` constants. */
|
||||
const INFINITY = 1 / 0
|
||||
|
||||
/**
|
||||
* Creates a set object of `values`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} values The values to add to the set.
|
||||
* @returns {Object} Returns the new set.
|
||||
*/
|
||||
const createSet = (Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY)
|
||||
? (values) => new Set(values)
|
||||
: () => {}
|
||||
|
||||
export default createSet
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user