structuredClone vs Deep Clone
intermediateWhen to use the built-in structuredClone, where it fails (functions, prototypes), and how it compares to JSON round-tripping.
Implement deep flatten for arbitrarily nested arrays in JavaScript — recursive and iterative solutions compared with Array.prototype.flat(Infinity).
Deep flattening is a technique used to convert a nested array into a single-dimensional array. Unlike shallow flattening, which only flattens the top level of nested arrays, deep flattening recursively flattens all levels of nested arrays.
Deep flattening is important because it:
Interviewers often test your understanding of deep flattening by asking you to:
Let's start with a basic implementation of a deep flatten function in JavaScript using recursion:
function deepFlatten(arr) {
return arr.reduce((acc, val) =>
Array.isArray(val) ? acc.concat(deepFlatten(val)) : acc.concat(val),
[]
);
}reduce to iterate through the array.Array.isArray to check if the current value is an array.Consider a nested array:
const nestedArray = [1, [2, [3, [4, [5]]]], 6];
const flattenedArray = deepFlatten(nestedArray);
console.log(flattenedArray); // Output: [1, 2, 3, 4, 5, 6]In this example:
deepFlatten function is used to recursively flatten the nested array into a single-dimensional array.Let's enhance our deep flatten function to handle edge cases such as empty arrays, non-array values, and deeply nested structures:
function deepFlatten(arr) {
if (!Array.isArray(arr)) {
throw new TypeError('Input must be an array');
}
return arr.reduce((acc, val) => {
if (Array.isArray(val)) {
return acc.concat(deepFlatten(val));
} else {
return acc.concat(val);
}
}, []);
}TypeError if it is not.For large arrays or deeply nested structures, performance can become a concern. Let's optimize the implementation using an iterative approach with a stack:
function deepFlatten(arr) {
const stack = [...arr];
const result = [];
while (stack.length) {
const next = stack.pop();
if (Array.isArray(next)) {
stack.push(...next);
} else {
result.push(next);
}
}
return result.reverse();
}while loop to process each element in the stack, pushing nested arrays back onto the stack for further processing.For a deeper understanding, try this coding challenge:
Challenge: Modify the deep flatten function to accept a depth parameter, allowing the array to be flattened up to a specified depth.
function deepFlatten(arr, depth = Infinity) {
if (!Array.isArray(arr)) {
throw new TypeError('Input must be an array');
}
return depth > 0 ?
arr.reduce((acc, val) =>
acc.concat(Array.isArray(val) ? deepFlatten(val, depth - 1) : val),
[]) :
arr.slice();
}
// Example usage with depth control
const nestedArray = [1, [2, [3, [4, [5]]]], 6];
console.log(deepFlatten(nestedArray, 2)); // Output: [1, 2, 3, [4, [5]], 6]
console.log(deepFlatten(nestedArray, 1)); // Output: [1, 2, [3, [4, [5]]], 6]
console.log(deepFlatten(nestedArray)); // Output: [1, 2, 3, 4, 5, 6]In this challenge:
depth parameter, allowing partial flattening up to the specified depth.When to use the built-in structuredClone, where it fails (functions, prototypes), and how it compares to JSON round-tripping.
Recursively clone nested objects and arrays, handling cycles with a WeakMap.
Structural equality for nested data: type checks, key comparison, and recursion done right.
Use a Proxy to support arr[-1] like Python — a practical introduction to Proxy traps.