This is the 21st day of my participation in the August Text Challenge.More challenges in August
preface
Array flattening is a common test in the interview, which not only tests the candidate’s ability to skillfully use various methods, but also tests his ability to flexibly program. Let’s look at six ways to flatten arrays.
One, ordinary recursive implementation
The idea of ordinary recursion is easy to understand, which is to flatten out each element layer by element through a for loop. If the current element is an array, recurse it and concatenate the results of the recursion into the result array.
Code implementation:
let arr = [1[2[3.4.5]]];
function flatten(arr) {
let result = [];
for(let i = 0; i < arr.length; i++) {
// The current element is an array, recursively flattening it
if(Array.isArray(arr[i])) {
// Concatenate the recursively flattened result into the result array
result = result.concat(flatten(arr[i]));
}
// Add to the result array
else{ result.push(arr[i]); }}return result;
}
console.log(flatten(a)); // [1, 2, 3, 4,5]
Copy the code
2. Reduce implementation
Reduce is a very powerful method in JS arrays and a functional programming API in JS.
The key to the recursive implementation above is to process each item of the array, and recursively process the array as it encounters it. Since we need loops and result arrays, we can use Reduce to simplify our code:
let arr = [1[2[3.4]]];
function flatten(arr) {
return arr.reduce(function(pre, cur){
return pre.concat(Array.isArray(cur) ? flatten(cur) : cur)
}, [])
}
console.log(flatten(arr));// [1, 2, 3, 4,5]
Copy the code
After reduce is used, the code is more concise. The first parameter of Reduce is used to return the final cumulative result, and the second parameter is the value of the element currently traversed. The idea of processing array elements and non-array elements is the same as the first method, and finally the processed results can be spliced into the cumulative result array and returned.
Extend operator implementation
The extension operator is one of the new features in ES6. It allows you to expand the first layer of an array directly by manipulating it. With this feature, you can flatten an array without recursion, because each recursion is an expansion of the current level of the array, which is what the extension operator does.
let arr = [1[2[3.4]]];
function flatten(arr) {
while (arr.some(i= > Array.isArray(i))) { arr = [].concat(... arr); }return arr;
}
console.log(flatten(arr)); // [1, 2, 3, 4,5]
Copy the code
Code used in the array of some another method, the purpose is to determine whether the current array and array elements, if there is an array for a layer, the results will open at the same time as the next judgment conditions, such as peeling Onions, layer-by-layer peeling an onion skin, when the loop condition does not meet the infant has no array elements in the array, This is an array that has been completely flattened.
Four, split + toString implementation
We can also use split and toString methods to flatten arrays together. ToString is a method on the Object prototype chain. Since all objects in JS are derived from Object objects, they can all call toString, although different objects may rewrite this method to output their desired format. The toString method of an array converts the array to a string separated by commas. It internally flattens the array into one dimension before converting it to a string. So we can first flatten the array using toString, and then duplicate an array containing all elements by separating each element with commas using the split method. So we can flatten the array.
let arr = [1[2[3.4]]];
function flatten(arr) {
return arr.toString().split(', ').map(i= >Number(i));
}
console.log(flatten(arr)); // [1, 2, 3, 4]
Copy the code
Note, however, that although this method is very simple, it has some limitations. For an array containing elements of a reference type, a conversion will occur during toString, which will result in an exception, because toString of the reference type will be called for converting the reference type to a string. As mentioned above, different objects can overwrite it, for example, a function will get a code string for the function body instead of the function reference we want.
Therefore, using this approach depends on the element type.
Five, re + JSON implementation
We use the json.stringify method to convert the array to a string wrapped in parentheses separated by commas. For example, “[1, [2, [3, [4, 5]]], 6]”, it can be found from the converted characters that each pair of parentheses encloses a level. Flattening the array means eliminating all the inner levels and preserving only the outermost layer. In this case, replacing all the parentheses with empty characters will result in an element separated by a comma. Finally, the json.parse method is used to parse into an array object.
let arr = [1[2[3[4.5]]].6];
function flatten(arr) {
let str = JSON.stringify(arr);
str = str.replace(/(\[|\])/g.' ');
// Concatenate the outermost layer to a format parsed by JSON
str = '[' + str + '] ';
return JSON.parse(str);
}
console.log(flatten(arr)); // [1, 2, 3, 4,5]
Copy the code
Again, this approach has limitations when dealing with reference data types, as well as whether the element is a valid data type for JSON.
Six, Array. Prototype. Flat
Array.prototype.flat is a new Array method in ES6. Its function is to flaten arrays and determine the level of expansion according to the parameters passed in.
let arr = [1[2[3.4]]];
function flatten(arr) {
return arr.flat(Infinity);
}
console.log(flatten(arr)); // [1, 2, 3, 4,5]
Copy the code
Parameter Infinity indicates complete expansion, which is very convenient and fast to use.