【JS基础】数组铺平 - 栈的方式 | 递归 | 遍历

619 阅读2分钟

目录

  1. while 栈的方式
  2. reduce + 递归 的方式
  3. 遍历方式
  4. flat(Infinity)
  5. 如果数组中元素都是字符串,可以利用数组toString()方法

一、栈的方式

while + (原始数据:concat成栈,后pop + 若item是数组则push) + (否则:结果数组unshift)得到最终铺平的数组

// 栈思想
function flat(arr) {
  const result = []; 
  const stack = [].concat(arr);  // 将数组元素拷贝至栈,直接赋值会改变原数组
  //如果栈不为空,则循环遍历
  while (stack.length !== 0) {
    const val = stack.pop(); // 尾部弹出
    if (Array.isArray(val)) {
      stack.push(...val); //如果是数组再次入栈,并且展开了一层, 并且从尾部推入
    } else {
      result.unshift(val); //如果不是数组就将其取出来放入结果数组中,
      // 从头部插入,第一个插入的实际为result的最后一个。
      // 最后一个插入头部的实际为第一个。这就做到了尾部的还在尾部,头部的还在头部。
    }
  }
  return result;
}
const arr = [1, 2, 3,[4,[5]],6]
flat(arr);// [1, 2, 3, 4, 5, 6]

二、reduce方式+concat+ 递归

递归 concat可以铺平一级数组

function flat(arr){
   return  arr.reduce((pre, cur)=> pre.concat(Array.isArray(cur) ? flat(cur) : cur), [])
};
const arr = [1, 2, 3,[4,[5]],6]
flat(arr);// [1, 2, 3, 4, 5, 6]

三、 遍历方式 map 或 forEach

function flat1(arr){
    let res = [];
    arr.map((item,index)=>{ // arr.forEach一样可以
        if(Array.isArray(item)){
            res = res.concat(flat1(item));// concat的返回值才是组合后的数组。concat不改变原始数据
        }else{
            res.push(item); // push的返回值是数组的长度,一般没用。push会改变原始数据。
        }
    })
    return res;
}
const arr = [1, 2, 3,[4,[5]],6]
flat1(arr)
// [1, 2, 3, 4, 5, 6]

四 flat(Infinity)


[1, [2, [3]]].flat(Infinity);
// [1, 2, 3]

五 如果数组中元素都是字符串,可以利用数组toString()方法

var arr22= ['a',[`b`],`c`,[[`d`],`e`,[`f`,[`g`,`h`]]]]
console.log(arr22.toString().split(','))
// ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

元素是对象或者数字都会被转成字符串

var arr22= ['a',[{a1:1}],1,[[`d`],`e`,[`f`,[`g`,`h`]]]]
console.log(arr22.toString().split(','))
// ['a', '[object Object]', '1', 'd', 'e', 'f', 'g', 'h']

总结

  • 栈的方式: while + (原始数据:concat成栈,后pop + 若item是数组则push) + (否则:结果数组unshift)得到最终铺平的数组
  • concat的返回值才是组合后的数组。concat不改变原始数据
  • push的返回值是数组的长度,一般没用。push会改变原始数据。