LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

js数组扁平化:从‘千层饼’到‘一马平川’的六种神操作 🥞→📜

freeflydom
2025年6月5日 11:3 本文热度 130

一、生活场景:什么叫"数组不扁平"?

想象你收拾衣柜:

  • 千层饼数组[袜子, [裤子, [上衣, 腰带]], 鞋子](找双袜子要翻三层)
  • 扁平数组[袜子, 裤子,上衣,腰带,鞋子](一目了然)

需求:把嵌套数组变成一维数组,就是扁平化!


二、青铜选手:flat()方法(ES10真香)

const messyCloset = ['袜子', ['裤子', ['上衣', '腰带']], '鞋子'];
// 1. 默认只拍平一层
const level1 = messyCloset.flat(); 
// ['袜子', '裤子', ['上衣', '腰带'], '鞋子']
// 2. 传入Infinity直接全平
const allFlat = messyCloset.flat(Infinity);
// ['袜子', '裤子', '上衣', '腰带', '鞋子']

我的翻车史
曾经以为flat(2)flat(Infinity)效果一样,直到遇到五层嵌套数组...


三、白银选手:reduce+递归(经典永流传)

function flatten(arr) {
  return arr.reduce((result, item) => {
    return result.concat(
      Array.isArray(item) ? flatten(item) : item
    );
  }, []);
}
const myCloset = ['👖', ['👔', ['🧦']], '👟'];
console.log(flatten(myCloset)); // ['👖', '👔', '🧦', '👟']

适用场景

  • 需要兼容老浏览器时
  • 面试官盯着你手写实现时 😏

四、黄金选手:toString妙用(数字数组专属)

const numLayers = [1, [2, [3, [4]]]];
// 1. 转字符串再分割
const strFlat = numLayers.toString().split(','); 
// ['1', '2', '3', '4']
// 2. 转数字(需处理非数字项)
const numFlat = strFlat.map(Number); 
// [1, 2, 3, 4]

致命缺陷

  • 会把[1, 'a']变成['1', 'a']
  • 遇到null, undefined直接转字符串

五、铂金选手:生成器函数(优雅处理海量数据)

function* flattenGen(arr) {
  for (const item of arr) {
    Array.isArray(item) ? yield* flattenGen(item) : yield item;
  }
}
const hugeArray = [1, [2, [3, [4, ...[1000000个项]]]];
const flattened = [...flattenGen(hugeArray)]; // 按需生成不爆内存

性能优势
处理超大规模数组时,不会一次性占用大量内存


六、钻石选手:栈结构迭代(避免递归爆栈)

function flattenStack(arr) {
  const stack = [...arr];
  const result = [];
  
  while (stack.length) {
    const next = stack.pop();
    Array.isArray(next) ? stack.push(...next) : result.push(next);
  }
  
  return result.reverse();
}
const deepArray = [1, [2, [3, [4]]];
console.log(flattenStack(deepArray)); // [1, 2, 3, 4]

适用场景

  • 嵌套层级极深时(递归可能栈溢出)
  • 需要控制遍历顺序时

七、王者选手:Array.prototype.flatMap (ES2019)

// 先map再flat(1)的语法糖
const data = [1, [2], 3];
const processed = data.flatMap(item => 
  Array.isArray(item) ? item : [item * 2]
);
// [2, 2, 6] 

神技巧
flatMap实现过滤+展开二合一:

const mixed = [1, 2, , , 5];
const compact = mixed.flatMap(x => x || []);
// [1, 2, 5] (自动跳过空值)

八、终极选择指南

场景推荐方案原因
现代浏览器环境flat(Infinity)原生API性能最佳
需要兼容IEreduce+递归兼容性好
纯数字数组toString+split取巧但高效
超大数据量生成器函数内存友好
需要控制遍历顺序栈结构迭代避免递归爆栈
需要边处理边展开flatMap代码最简洁

九、真实案例:树形菜单扁平化

// 原始树形数据
const menuTree = [
  {
    name: '文件',
    children: [
      { name: '新建' },
      { name: '打开', children: [{ name: '从云端' }] }
    ]
  }
];
// 递归提取所有节点名
function getAllNames(items) {
  return items.flatMap(item => [
    item.name,
    ...(item.children ? getAllNames(item.children) : [])
  ]);
}
console.log(getAllNames(menuTree)); 
// ['文件', '新建', '打开', '从云端']


转自https://juejin.cn/post/7511969803557584937


该文章在 2025/6/5 11:03:14 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved