JS-五种数组扁平化方法总结

问题抛出:对于[1, [1,2], [1,2,3]这样多层嵌套的数组,我们如何将其扁平化为[1, 1, 2, 1, 2, 3]这样的一维数组呢(数组降维):

1、ES6 的 flat()

先来简单看一下关于它的使用:

const arr = [1, [1,2], [1,2,3]]
arr.flat(Infinity)  // [1, 1, 2, 1, 2, 3]

note:

MDN:flat() 方法会按照一个可指定的深度(传入的参数)递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回

Array.prototype.flat() 特性总结:

  • 用于将嵌套的数组扁平化,变成一维的数组。该方法返回一个新数组,对原数据没有影响。
  • 不传参数时,默认扁平化一层,可以传入一个整数,表示想要扁平化的层数。
  • 传入 <=0 的整数将返回原数组,不扁平化
  • Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组
  • 如果原数组有空位,Array.prototype.flat() 会跳过空位。

方法虽好,但是使用这个方法前要先考虑一下兼容性问题哦!!!

我们来实现一个 flat 吧!!!

note:

MDN:reduce() 方法对数组中的每个元素执行一个由提供的reducer函数(升序执行),将其结果汇总为单个返回值

// 传入两个参数:数组arr  扁平化层数depth(默认是一层)
function flat (arr, depth = 1) {
    return depth > 0 ?  // 层数大于0才进行扁平化
        arr.reduce((acc, cur) => {  // acc:reducer 函数的返回值(累计器),cur:当前值(arr 中遍历到的当前元素值)
            if (Array.isArray(cur)) {  // 当前值是 数组
                return [...acc, ...flat(cur, depth - 1)];  // 递归执行 flat 函数,插入返回数组中 累计器的值后面
            }
            return [...acc, cur];   // 当前值不是数组,直接插入返回数组中 累计器后面
        }, [])
        : arr // 扁平化层数小于等于0,直接返回原数组 arr
}

2、序列化后正则

const arr = [1, [1,2], [1,2,3]]
const str = `[${JSON.stringify(arr).replace(/(\[|\])/g, '')}]`
JSON.parse(str)   // [1, 1, 2, 1, 2, 3]

3、递归

对于树状结构的数据,最直接的处理方式就是递归

const arr = [1, [1,2], [1,2,3]]
function flat(arr) {
  let result = []
  for (const item of arr) {
    item instanceof Array ? result = result.concat(flat(item)) : result.push(item)
  }
  return result
}

flat(arr) // [1, 1, 2, 1, 2, 3]

4、reduce()递归

const arr = [1, [1,2], [1,2,3]]
function flat(arr) {
  return arr.reduce((acc, cur) => {
    return acc.concat(cur instanceof Array ? flat(cur) : cur)
  }, [])
}

// 或者
function flat(arr) { 
    return Array.isArray(arr)
      ? arr.reduce( (acc, cur) => [...acc, ...flattenDeep(cur)] , [])
      : [arr]
}

flat(arr)  // [1, 1, 2, 1, 2, 3]

5、迭代+展开运算符

// 每次while都会合并一层的元素,这里第一次合并结果为[1, 1, 2, 1, 2, 3, [4,4,4]]
// 然后arr.some判定数组中是否存在数组,因为存在[4,4,4],继续进入第二次循环进行合并
let arr = [1, [1,2], [1,2,3,[4,4,4]]]
while (arr.some(Array.isArray)) {
  arr = [].concat(...arr);
}

console.log(arr)  // [1, 1, 2, 1, 2, 3, 4, 4, 4]

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值