Directory
(Free learning recommendation: javascript video tutorial)
1. Recursion
The for loop is the easiest thing to think of when we perform array operations, when time and space complexity are not considered. , recursion should be a perfect choice!
Example:
输入 const arr = [1, [2, [3, 4, { a: 1 }], null], undefined];` 输出 [ 1, 2, 3, 4, { a: 1 }, null, undefined ]
Code:
function flatten(arr) { let res = []; for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { // 因为函数返回的是数组,所以要做拼接处理 res = res.concat(flatten(arr[i])); } else { res.push(arr[i]) } } return res;}
Note:
2. reduce
Let’s first take a look at what reduce
does: reduce( )
method executes a reducer function
provided by you (executed in ascending order) on each element in the array, summarizing its results into a single return value.
Example:
输入 const arr = [1, [2, [3, 4, { a: 1 }], null], undefined];` 输出 [ 1, 2, 3, 4, { a: 1 }, null, undefined ]
Code:
function flatten(arr) { return arr.reduce((prev, next) => { // prev表示上一次操作的结果 return prev.concat(Array.isArray(next) ? flatten(next) : next) }, []) // 注意reduce的初始值应该是[],否则无法进行拼接}
Note:
Carefully compare Method 1 and Method 2. The two ideas are exactly the same - find the sub-elements whose data type is the array and smooth them out, but the implementation details are slightly different. different.
The only thing that needs attention is that the basic type of data must start with an array when splicing.
3. apply some
Since method two is a variation of method one, method three can also be said to be a variation of method two, but it does not use recursion. method, but a method of "dismantling" nesting layer by layer
Let's first look at the API used:
apply
: Call an A function given a this value, and arguments in the form of an array (or array-like object). some
: Test whether at least one element in the array passes the provided function test. It returns a Boolean type valueCode:
function flatten(arr) { while (arr.some(item => Array.isArray(item))) { // 只要存在数组类型的元素,就抹平一层 arr = [].concat.apply([], arr) } return arr;}
Note:
Everyone is confused The main point is apply
. In fact, the main purpose is to reduce the brackets
let res = [];res = res.concat({});// 等价于[].concat.apply([], [{}])
. In this example:
arr = [].concat.apply([], arr);// 等价于[].concat(1, [2, [3, 4, { a: 1 }], null], undefined)
4. ES6 expansion operator
You may have also noticed that from Methods 1 to 3, we continue to use existing methods to streamline the amount of our code. The same is true for this method~
We use the expansion operator of ES6 ( Used to take out all traversable attributes of the parameter object and copy them to the current object), continue to streamline method three:
Code:
function flatten(arr) { while (arr.some(item => Array.isArray(item))) { // 只要存在数组类型的元素,就抹平一层 arr = [].concat(...arr) } return arr;}
Five. toString
If the first four methods are the mainstream methods that we can implement, then the next few are the "non-mainstream" methods that we can implement, just go to the code!
function flatten(arr) { return arr.toString().split(',').map(function(item){ return +item })}
Note:
There are type restrictions when converting data. If the original data is like this: [1, '2'], then problems will occur.
6. Regularity
If we default to the defect that the type will be converted, we can also flatten the array in a more violent way:
function flatten(arr) { return JSON.stringify(arr).replace(/\[|\]/g, '').split(',');}
Note:
If it is a pure array, there seems to be no problem
function flatten(arr) { return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '').split(',') + ']')}
But if the array contains objects, you need to eliminate the consequences after JSON, so More rigorous~
At this point, the six methods include most of the implementations of array flattening. So what if we want to "upgrade" our method into a tool? At this time we have to "plagiarize" loadsh~
7. Implement your own flat tool method
Here we The flatten function in loadsh is simplified. Let’s look at the code for specific changes:
/* * @private * @param {Array} array 需要扁平化的数组 * @param {number} depth 最多处理几层 * @param {boolean} [isStrict] 是否严格处理函数 * @param {Array} [result=[]] 输出的数组 * @returns {Array} */function flatten(array, depth, isStrict, result) { result || (result = []) // 边界 if (array == null) return result; for (const value of array) { if (depth > 0 && Array.isArray(value)) { if (depth > 1) { flatten(value, depth - 1, isStrict, result) } else { result.push(...value); // 只拆1层 } } else if (!isStrict) { result[result.length] = value } } return result;}
const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 1, false);// [ 1, 2, 3, 4, [ 5, 6 ], { a: 1 }, null, undefined ]
const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 1, true);// [ 3, 4, [ 5, 6 ] ]const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 2, true);// [ 5, 6 ]
isStrict
After the parameter is turned on, the exposed elements are retained after flattening, and the shallow elements are eliminated.
Writing here, we have understood the flattening processing ideas and have certain implementation capabilities. If you can fully understand the above code, I believe that the flattening part should not be difficult for you. Let’s next This article continues to study another method of loadsh~
Related free learning recommendations:javascript(Video)
The above is the detailed content of JavaScript Topic 8: Array Flattening. For more information, please follow other related articles on the PHP Chinese website!