数组拍平啦啦啦啦~

还是照旧贴上写的很好的博客。。。
数组拍平1

接下来就自己复述阶段啦数组拍平啦啦啦啦~_第1张图片

1、人家数组有自己拍平的方法flat啊,(还用得着自己写?)

arr.flat(Infinity)//不管你多少层都拍成1层
arr.flat(1)// [ 1, [ 2 ], [ 3, [ 4, 5 ] ] ]=>[ 1, 2, 3, [ 4, 5 ] ],只拍平了第一层的元素
arr.flat()//不传值,默认为arr.flat(1)

要注意的一个点啦:

  • arr.flat()是返回值新的改变的数组,但是原来的数组并没有改变哦。
  • 如果原数组有空位,flat()方法会跳过空位。
[1, 2, , 4, 5].flat()
// [1, 2, 4, 5]

2、朴素的处理方式(递归

function fn(arr) {
  let arr1 = []
  arr.forEach((val) => {
    if (val instanceof Array) {
      arr1 = arr1.concat(fn(val))
    } else {
      arr1.push(val)
    }
  })
  return arr1
}

3、把递归讲的更高大上的方式(+reduce
利用reduce,就省掉了定义新数组,循环的书写,实际上还是一样一样的内涵啦。

function fn(arr) {
  return arr.reduce((prev, cur) => {
    return prev.concat(Array.isArray(cur) ? fn(cur) : cur)
  }, [])
}

如果用上面那种?:的话,递归也可以写成

function fn(arr) {
  let arr1 = []
  arr.forEach((val) => {
    Array.isArray(val) ? arr1 = arr1.concat(fn(val)) : arr1.push(val)
  })
  return arr1
}

差别就是reduce自带初始化格式,递归还是第一种吧,比较明了啊

4、拓展运算符+while循环

原理:扩展运算符也是拍平一层的作用,所以要用while循环,循环的条件就是还有元素是数组的样子。

//ary.some(Array.isArray)等于ary.some((val) => Array.isArray(val))
while (ary.some(Array.isArray)) {
  ary = [].concat(...ary);//...作为参数传入,拼接数组和字符,即可拍平一层
}

所以,如果要模拟flat函数的话,扩展运算符应该是最方便的一种方法。

Array.prototype.myflat = function (k) {
  let temp = this//指向调用这个函数的数组
  while (k > 0) {
    temp = [].concat(...temp)
    k--
  }
  return temp
}

5、奇技淫巧之toString+split

原理:转成字符后,然后以逗号分隔即可。

//[1, 2, 3, 4].toString()=>1,2,3,4
let arr1 = arr.toString().split(',').map((val) => {
  return parseInt(val)
})

注意点:不一定返回的是parseInt后的val,如果是字符类型直接return val即可。

6、奇技淫巧之JSON.stringify()+replace+split
原理:同样是转字符,但是这个方法是连带数组的[]都包括的。所以,加上splice来去掉比较合适。

//JSON.stringify([1, 2, 3, 4]) =>[1,2,3,4]
let str = JSON.stringify(arr)
let arr1 = str.replace(/\[|\]/g, '').split(',').map(val => parseInt(val))

以上。

你可能感兴趣的:(前端小芝士)