Flattens array
Symbol.isConcatSpreadable
The Symbol.isConcatSpreadable
well-known symbol is used to configure if an object should be flattened to its array elements when using the Array.prototype.concat()
method.
const alpha = ['a', 'b', 'c'];
const numeric = [1, 2, 3];
let alphaNumeric;
alphaNumeric = alpha.concat(numeric);
console.log(alphaNumeric); // Result: ['a', 'b', 'c', 1, 2, 3]
numeric[Symbol.isConcatSpreadable] = false;
alphaNumeric = alpha.concat(numeric);
console.log(alphaNumeric); // Result: ['a', 'b', 'c', [1, 2, 3] ]
Array-like objects For array-like objects, the default is to not spread. Symbol.isConcatSpreadable needs to be set to true in order to get a flattened array:
const numeric = [1, 2, 3];
const fakeArray = {
0: 'hello',
1: 'world',
length: 2,
};
numeric.concat(fakeArray); // Result: [1, 2, 3,{0: 'hello',1: 'world' ,length: 2}]
// Symbol.isConcatSpreadable needs to be set to true in order to get a flattened array
fakeArray[Symbol.isConcatSpreadable] = true;
numeric.concat(fakeArray); // Result: [1, 2, 3, "hello", "world"]
isFlattenable
Checks if value
is a flattenable arguments
object or array.
const spreadableSymbol = Symbol.isConcatSpreadable;
function isFlattenable(value) {
// Array-like objects
// !!(value && value[spreadableSymbol])
return Array.isArray(value) || !!(value && value[spreadableSymbol]);
}
baseFlatten ⭐️
The base implementation of flatten
with support for restricting flattening.
function baseFlatten(array, depth, predicate, isStrict, result = []) {
if (array == null) {
return result;
}
for (const value of array) {
if (depth > 0 && predicate(value)) {
if (depth > 1) {
baseFlatten(value, depth - 1, predicate, isStrict, result);
} else {
result.push(...value);
}
} else if (!isStrict) {
result[result.length] = value;
// result.push(value)
}
}
return result;
}
📝Note
- undefind == null // -> true
flatten
flatten array a single level deep
function flatten(array) {
if (array == null) {
return [];
}
return baseFlatten(array, 1);
}
flattenDeep
Recursively (递归) flattens array.
const INFINITY = 1 / 0;
function flattenDeep(array) {
if (array == null) {
return [];
}
return baseFlatten(array, INFINITY);
}
flattenDepth
function flattenDepth(array, depth = 1) {
if (array == null) {
return [];
}
return baseFlatten(array, +depth);
}
Note
+depth
equalNumber(depth)