提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
javascript实现数组扁平化的七种方式
前言
提示:这里可以添加本文要记录的大概内容:
数组扁平化是面试中的常考点,不仅考验面试者熟练使用各类方法的能力,还考验其灵活编程的能力。下面让我们来看下实现数组扁平化的七种方式。
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是扁平化?
定义 : 扁平化就是将多维数组变成一维数组,不存在数组的嵌套
二、实现扁平化的方法 封装 flatten
1.最简单的方式( ES6 flat)
Array.prototype.flat是ES6新增的一个数组方法,它的作用就是用来数组扁平化,并且根据传入的参数来决定展开的层级。
参数:
depth(可选) 指定要提取嵌套数组的结构深度,默认值为 1
返回值:
返回一个新数组,包含数组与提取嵌套数组的所有元素的新数组
使用 Infinity,可展开任意深度的嵌套数组
代码如下(示例):
let arr = [1, [2, [3, 4]]];
function flatten_1(arr) {
return arr.flat(Infinity);
}
console.log(flatten(arr)); // [1, 2, 3, 4]
直接使用自带的方法可以很快的实现, 但是很显然我们面试的时候如果只会这种方法是不行的。
2.普通递归实现(使用for循环或者forEach都可以)
普通递归的思路很容易理解,就是通过for循环的方式,逐层逐个元素地去展平,如果当前元素是一个数组,那么就对它进行递归处理,再将递归处理的结果拼接到结果数组上。
代码如下(示例):
let arr = [1, [2, [3, 4, 5]]];
function flatten_2(arr) {
let result = []
for(let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) {
//console.log('数组');
result = result.concat(flatten(arr[i]));
}
else {
result.push(arr[i])
}
}
return result
}
console.log(flatten_2(arr)); //[1,2,3,4,5]
增加参数控制扁平化深度(相当于手写flat()方法)
// // forEach 遍历数组会自动跳过空元素
const eachFlat = (arr = [],depth = 1)=> {
const result = [];
(function flat(arr, depth){
arr.forEach((item) => {
// 控制递归深度
if(Array.isArray(item) && depth > 0) {
flat(item,depth - 1)
}
else {
// 缓存元素
result.push(item)
}
});
})(arr, depth)
return result
}
console.log(eachFlat(arr,1)); // [ 1, 2, [ 3, 4, 5 ] ]
console.log(eachFlat(arr,2)); // [ 1, 2, 3, 4, 5 ]
3、split + toString方法
我们也可以通过 split 和 toString 两个方法,来共同实现数组扁平化。
let arr3 = [1, [2, [3, [4,5]]]];
function flatten_3(arr) {
return arr.toString().split(',').map(item=>Number(item))
}
console.log(flatten_3(arr3)); // [1,2,3,4,5]
不过需要注意的是,虽然这个方法非常简单,但具有一定的局限性,对于包含引用类型元素的数组来说,在toString过程中会发生类型转换,从而使得转换结果异常,因为对于引用类型转成字符串,会调用引用类型的toString,上面提到不同对象会对它进行改写,例如函数就会得到一个函数体的代码字符串,而不是我们想要的函数引用。
4、扩展运算符实现
扩展运算符是ES6的新特性之一,用它操作数组可以直接展开数组的第一层,利用这个特性,我们可以不使用递归来实现数组的展平,这是因为每一次递归都是对当前层次数组的一次展开,而扩展操作符就是干这工作的。
let arr4 = [1, [2, [3, 4]]];
function flatten_4(arr) {
while(arr.some(item=> Array.isArray(item))) {
//console.log(...arr);
arr = [].concat(...arr)
//console.log(arr,'arr');
}
return arr
}
console.log(flatten_4(arr4));
5、 使用正则替换
看到嵌套的数组,如果在字符串的角度上看就是多了很多[ 和],如果把它们替换就可以实现简单的扁平化
let arr5 = [1, [2, [3, 4]]];
// console.log(JSON.stringify(arr5));
// console.log(JSON.stringify(arr5).replace(/(\[|\])/g, ''));
function flatten5(arr) {
let str = JSON.stringify(arr).replace(/(\[|\])/g, '')
str = '['+ str +']'
//console.log(str,'str'); // '[1,2,3,4]' String
return JSON.parse(str) // [1,2,3,4]
}
console.log(flatten5(arr5));
6、巧用 reduce方法
reduce是JS数组中非常强大的一个方法,同时也是JS中的一个函数式编程API。
const arr = [1, [2, [3, 4]]];
const flatten = (arr, deep = 1) => {
if (deep <= 0) return arr;
return arr.reduce((res, curr) => res.concat(Array.isArray(curr) ? flatten(curr, deep - 1) : curr), [])
}
console.log(arr, 2);
// 输出:[ 1, 2, 3, 4 ]
7、使用 Generator 函数
GeneratorFunction是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行),这里的generator方法的思想也是迭代的(当然前面我迭代的代码,可以把判断是否是array的条件放在if条件当中)。
它不同于普通函数,是可以暂停执行的,所以函数名之前要加星号,以示区别。
let arr7 = [1, [2, [3, 4]]];
function* flatten7(array) {
for (const item of array) {
if (Array.isArray(item)) {
yield* flatten7(item);
} else {
yield item;
}
}
}
const gen = flatten7(arr7)
let res = []
for (let f of gen) {
res.push(f)
}
console.log(res); [1,2,3,4]
//需要注意的是,调用flatten7(arr7)并不会直接得到结果,需要时用next()或者放在for循环中得到所有结果。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。