var isArray = Array.isArray;
var sourceArray = [1, [1, 2, [3, 4, [5, 6]]], 2, [3, 4, [1, 2, [3, [1, 2, [3, 4]], 4]], [5, 6, [1, 2, [3, 4, [5, 6]]], [7, 8, [9, 10]]]]];
function flatPush(arr, depth) {
if (depth === undefined) { depth = 100; } else if (depth <= 0) { return arr; }
var result = [];
for (var len = arr.length, i = 0, val; i < len; ++i) {
if (isArray((val = arr[i]))) {
val = flatPush(val, depth - 1);
for (var jen = val.length, j = 0; j < jen; ++j) { result.push(val[j]); }
} else {
result.push(val);
}
}
return result;
}
function flatConcat(arr, depth) {
if (depth === undefined) { depth = 100; } else if (depth <= 0) { return arr; }
var result = [];
for (var len = arr.length, i = 0, val; i < len; ++i) {
if (isArray((val = arr[i]))) {
result = result.concat(flatConcat(val, depth - 1));
} else {
result.push(val);
}
}
return result;
}
function flatSpread(arr, depth) {
if (depth === undefined) { depth = 100; } else if (depth <= 0) { return arr; }
var result = [];
for (var len = arr.length, i = 0, val; i < len; ++i) {
if (isArray((val = arr[i]))) {
result.push(flatSpread(val, depth - 1));
} else {
result.push(val);
}
}
return result;
}
return sourceArray.flat(100);
return flatPush(sourceArray);
return flatConcat(sourceArray);
return flatSpread(sourceArray);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
native flat | |
flatPush | |
flatConcat | |
flatSpread |
Test name | Executions per second |
---|---|
native flat | 405369.7 Ops/sec |
flatPush | 196251.7 Ops/sec |
flatConcat | 216556.4 Ops/sec |
flatSpread | 259593.6 Ops/sec |
I'll break down the provided benchmark and its test cases to explain what's being tested, compared, and the pros/cons of each approach.
Benchmark Definition The benchmark compares three approaches for implementing array flattening in JavaScript:
Array.prototype.flat()
(native implementation)flatPush
functionflatConcat
functionflatSpread
functionTest Case Descriptions
This test case uses the native Array.prototype.flat()
method, which is a built-in JavaScript function introduced in ES6.
flat()
method flattens an array and returns a new array with no prototypes.depth
to specify the maximum number of times the array can be recursively flattened.Pros:
Cons:
This test case uses a custom flatPush
function that recursively flattens an array.
function flatPush(arr, depth) {
if (depth === undefined) { depth = 100; }
else if (depth <= 0) { return arr; }
var result = [];
for (var len = arr.length, i = 0, val; i < len; ++i) {
if (isArray((val = arr[i]))) {
val = flatPush(val, depth - 1);
for (var jen = val.length, j = 0; j < jen; ++j) { result.push(val[j]); }
} else {
result.push(val);
}
}
return result;
}
depth
parameter.flat()
.Pros:
flat()
method is insufficient.Cons:
This test case uses a custom flatConcat
function that recursively flattens an array using the concat
method.
function flatConcat(arr, depth) {
if (depth === undefined) { depth = 100; }
else if (depth <= 0) { return arr; }
var result = [];
for (var len = arr.length, i = 0, val; i < len; ++i) {
if (isArray((val = arr[i]))) {
result = result.concat(flatConcat(val, depth - 1));
} else {
result.push(val);
}
}
return result;
}
flatPush
, but uses the concat
method instead of array spread.concat
.Pros:
flatPush
.depth
parameter.Cons:
flatPush
.flat()
.This test case uses a custom flatSpread
function that recursively flattens an array using the spread operator (...
).
function flatSpread(arr, depth) {
if (depth === undefined) { depth = 100; }
else if (depth <= 0) { return arr; }
var result = [];
for (var len = arr.length, i = 0, val; i < len; ++i) {
if (isArray((val = arr[i]))) {
result.push(...flatSpread(val, depth - 1));
} else {
result.push(val);
}
}
return result;
}
flatPush
, but uses the spread operator instead of array concatenation.Pros:
flatPush
.depth
parameter.Cons:
flatPush
.flat()
.Comparison Summary
Approach | Pros | Cons |
---|---|---|
Native flat | Built-in, easy to use | Limited control over flattening process |
flatPush | Flexible and customizable | Additional code complexity, performance concerns |
flatConcat | More readable than flatPush | Similar performance concerns as flatPush |
flatSpread | Concise and easier to read than flatPush | Similar performance concerns as flatPush |
Ultimately, the choice of approach depends on your specific use case requirements and performance considerations.
Example Use Case
For example, if you need to flatten an array with a large number of nested arrays, using the native flat()
method might be a good choice. However, if you want more control over the flattening process or need to handle edge cases where the built-in flat()
method is insufficient, one of the custom approaches (e.g., flatPush
, flatConcat
, or flatSpread
) might be more suitable.
Keep in mind that the performance characteristics and complexity of each approach can vary depending on your specific use case.