/**
* 根据depth递归减少array的嵌套层级
* Recursively flatten `array` up to `depth` times.
* @param {Array} The array to flatten
* @param {number} [depth=1] The maximum recursion depth.
* @returns {Array} Returns the new flattened array.
* @example
*
* var array = [1, [2, [3, [4]], 5]]
* flattenDepth(array, 1)
* // => [1, 2, [3, [4]], 5]
* flattenDepth(array, 2)
* // => [1, 2, 3, [4], 5]
*/
const NAN = 0 / 0
const INFINITY = 1 / 0
const symbolTag = "[object Symbol]"
const MAX_INTEGER = Number.MAX_VALUE || 1.7976931348623157e308
function isObjectLike(value) {
return typeof value == "object" && value !== null
}
function isSymbol(value) {
return (
typeof value === "symbol" ||
(isObjectLike(value) && Object.prototype.toString.call(value) === symbolTag)
)
}
function toNumber(value) {
if (typeof value === "number") {
return value
}
if (isSymbol(value)) {
return NAN
}
return Number(value)
}
function toFinite(value) {
if (!value) {
return value === 0 ? value : 0
}
value = toNumber(value)
if (value === INFINITY || value === -INFINITY) {
var sign = value < 0 ? -1 : 1 //可用Math.sign代替
return sign * MAX_INTEGER
}
return value === value ? value : 0 //NaN 不等于 NaN
}
function toInteger(value) {
var result = toFinite(value)
var remainder = result % 1
return result === result ? (remainder ? result - remainder : result) : 0 //可用Math.trunc代替
}
//内置的Symbol.isConcatSpreadable符号用于配置某对象作为Array.prototype.concat()方法的参数时是否展开其数组元素
const spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined
// Appends the elements of `value` to `array`
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length
while (++index < length) {
array[offset + index] = values[index]
}
return array
}
// Checks if `value` is likely an `arguments` object
function baseIsArguments(value) {
return isObjectLike(value) && Object.prototype.toString.call(value) === argsTag
}
const isArguments = baseIsArguments(
(function() {
return arguments
})()
)
? baseIsArguments
: function(value) {
return (
isObjectLike(value) &&
Object.prototype.hasOwnProperty.call(value, "callee") &&
!Object.prototype.propertyIsEnumerable.call(value, "callee")
)
}
// Checks if `value` is a flattenable `arguments` object or array
function isFlattenable(value) {
return (
Array.isArray(value) ||
isArguments(value) ||
!!(spreadableSymbol && value && value[spreadableSymbol])
)
}
// Flattens `array` a single level deep.
function baseFlatten(array, depth, predicate, isStrict, result) {
var index = -1,
length = array.length
predicate || (predicate = isFlattenable)
result || (result = [])
while (++index < length) {
var value = array[index]
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// Recursively flatten arrays
baseFlatten(value, depth - 1, predicate, isStrict, result)
} else {
arrayPush(result, value)
}
} else if (!isStrict) {
result[result.length] = value
}
}
return result
}
function flattenDepth(array, depth) {
var length = array == null ? 0 : array.length
if (!length) {
return []
}
depth = depth === undefined ? 1 : toInteger(depth)
return baseFlatten(array, depth)
}
export default flattenDepth