js 手动实现数组扁平化

518 阅读1分钟

手动实现数组扁平化(降维)

数组扁平化是指将一个多维数组转化为一维数组。

[1,2,3,[4,5]] ---> [1,2,3,4,5]

实现方法

  • ES6的flat方法

var newArray = arr.flat([depth])

参数:depth:指定要提取嵌套数组的结构深度,默认值为1,infinity:为无限大

const animals = ["🐷", ["🐶", "🐂"], ["🐎", ["🐑", ["🐲"]], "🐛"]];

// 不传参数时,默认“拉平”一层 

animals.flat(); // ["🐷", "🐶", "🐂", "🐎", ["🐑", ["🐲"]], "🐛"] 

// 传入一个整数参数,整数即“拉平”的层数 

animals.flat(2); // ["🐷", "🐶", "🐂", "🐎", "🐑", ["🐲"], "🐛"] 

// Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组

animals.flat(Infinity); // ["🐷", "🐶", "🐂", "🐎", "🐑", "🐲", "🐛"] 

// 传入 <=0 的整数将返回原数组,不“拉平” 

animals.flat(0); animals.flat(-10); // ["🐷", ["🐶", "🐂"], ["🐎", ["🐑", ["🐲"]], "🐛"]];

const testArray = [1,2,[3,4],[5,[6,7]]]
const resultArray = testArray.flat(Infinity)
console.log(resultArray);//[1,2,3,4,5,6,7]

如何实现一个flat函数

  • 实现思路
    • 遍历数组的每个元素 for循环、forEach()、map()等
    • 判断元素是否是数组 instanceof、isArray、constructor等
    • 将数组的元素展开一层 concat + apply、toString + split、扩展运算符 + concat等
const arr = [1, 2, 3, 4, [1, 2, 3, [1, 2, 3, [1, 2, 3]]], 5, "string", { name: "同学" }];

// concat + 递归

function flat(arr) { 
    let arrResult = []; 
    arr.forEach(item => { 
      if (Array.isArray(item)) {
         arrResult =arrResult.concat(flat(item)); // 递归 
    } else { 
        arrResult.push(item); 
    } 
   }); 
    return arrResult; 
 } 
flat(arr) // [1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 1, 2, 3, 5, "string", { name: "同学" }];


// 扩展运算符
function flat(arr){
   while(arr.some(item=>Array.isArray(item))){
     arr = [].concat(...arr)
   }
   return arr
}


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

//toString & split
function flat(arr){
    return arr.toString().split(',').map(function(item){
      return Number(item)
    })
}

题外

问题:数组有可能存在空位的情况

const arr = [1,2.[3,4],,]

此时,可以使用forEach + 递归实现flat函数

const arr = [1,[2,3],,,]
Array.prototype.fakeFlat = function(num = 1){
   if(!Number(num) || Number(num)<0){
      return this
   }
   let arr = []
   this.forEach(item =>{
      if(Array.isArray(item)){
         arr = arr.concat(item.fakeFlat(--num))
      }else {
         arr.push(item)
      }
   })
   return arr;
}