数组扁平化【JS】

本文详细探讨了数组扁平化的多种实现方案,包括递归结合concat或...、while循环与扩展运算符、栈结构、reduce函数、flat API以及toString/split组合。通过实例演示和原理解析,助你理解并掌握数组扁平化的各种技巧。
摘要由CSDN通过智能技术生成

前言

今天整理一道面试中的经典高频题:数组扁平化。先说一下什么是数组扁平化,简单来说就是把多为数组的元素按顺序放置在一维数组中,使其扁平。比如说[1, 2, 3, 4]这是一个拥有3个元素的数组,是一个一维数组(不存在数组嵌套)。[[1, 2, 3], [4, 5], [6, 7]]从整体上看是一个数组,但是其中的元素又是数组,即数组中嵌套数组。可以有二维,三维,n维数组。而数组扁平化就是把多为数组转化成一维数组,比如上文中的二维数组通过扁平化就变成[1, 2, 3, 4, 5, 6, 7]

那么实现数组扁平化有哪些方案呢?

实现数组扁平化的方案

1. 递归

递归的思路非常简单,递归遍历数组的每一项,判断该元素是否为数组,如果为数组时递归进入该数组遍历每一项,如果不为数组则concat或者使用ES6拓展运算符...

1.1 递归+concat

function flat(arr){
    let ret = []
    for(let key in arr){
        if(Array.isArray(arr[key])){
            ret = ret.concat(flat(arr[key]))
        }else{
            ret.push(arr[key])
        }
    }
    return ret
}

1.2 递归+...

function flat(arr){
    let ret = []
    for(let key in arr){
        if(Array.isArray(arr[key])){
           // ret = [...ret, ...flat(arr[key])]
          ret = ret.concat(...flat(arr[key]))
        }else{
            ret.push(arr[key])
        }
    }
    return ret
}

2 while+ES6拓展运算符

es6的拓展运算符能将二维数组变为一维数组,若arr中含有数组则使用一次拓展运算符,直到没有为止。

function flat(arr){
    while(arr.some(item => {
       return Array.isArray(item)
    })){
        arr = [].concat(...arr)
    }
    return arr
}

3 使用栈思想

其实就是抛去递归,用一个栈数组存取当前需要遍历的数组,不为数组则放到结果数组,为数组则压栈。

function flat(arr){
    let stack = arr
    let ret = []
    while(stack.length){
        let item = stack.pop()
        if(Array.isArray(item)){
            stack.push(...item)
        }else{
            ret.unshift(item)
        }
    }
    return ret
}

4 reduce实现

先说一下Array原型上的reduce函数。

reduce方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算 为一个值
reduce可以作为一个高阶函数,用于函数的compose
reduce对于空数组是不会执行回调函数的

function flat(arr){
    return arr.reduce((total, item) => {
       return total.concat(Array.isArray(item) ? flat(item) : item)
    }, [])
}

5 flat实现

flat()函数创建一个新数组,其中所有自数组元素都以递归方式连接到该数组中,直到达到指定的深度为止

let arr = [1, 2, 3, [4, 5, [6, 7], 8, [9, [[10], 11, 12]]]];
console.log(arr.flat(2))	//[1, 2, 3, 4, 5, 6, 7, 8, 9, [9, [[10], 11, 12]]]

let arr = [1, 2, 3, [4, 5, [6, 7], 8, [9, [[10], 11, 12]]]];
console.log(arr.flat(Infinity))	// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

6 toString+split实现

调用数组的toString方法,将数组变为字符串然后再用split分割还原为数组。split分割后形成的数组的每一项值为字符串,所以需要用一个map方法遍历数组将其每一项转换为数值型。

function flatten(arr) {
    console.log(arr.toString());// 1,2,3,4,5,6
    console.log(arr.toString().split(',')); //[ '1', '2', '3', '4', '5', '6' ]
    return arr.toString().split(',').map(function(item) {
        return Number(item);
    })
} 
let ary = [1, [2, [3, [4, 5]]], 6];
console.log(flatten(ary)); // [ 1, 2, 3, 4, 5, 6 ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值