javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript二维数组转为一维数组

JavaScript数组降维之将二维数组转为一维数组的五种方案

作者:yqcoder

本文介绍了五种数组降维方法,从最简单的Array.prototype.flat()方法,到兼容旧版本的concat;spread方法,再到通用的reduce方法,以及处理任意深度嵌套的递归方法, 兌时建议总结不同方法的特点、适用场景和性能差异,需要的朋友可以参考下

在处理数据时,我们经常会遇到这样的结构:

const arr = [
  [1, 2],
  [3, 4],
  [5, 6],
];

我们希望把它变成:

[1, 2, 3, 4, 5, 6];

这个过程被称为 “数组扁平化” (Array Flattening)

很多开发者知道 flat(),但你知道它有哪些替代方案吗?在兼容性要求高的老项目中该怎么办?如果数组层级不确定又该如何处理?

本文将带你掌握 5 种 主流方法,从最简单到最底层,彻底搞定数组降维。

1. 首选方案:Array.prototype.flat()

这是 ES2019 (ES10) 引入的最简单、最直观的方法。

基本用法

flat() 方法会创建一个新数组,其中所有子数组元素以递归方式连接到指定深度。

const arr = [
  [1, 2],
  [3, 4],
  [5, 6],
];

// 默认只扁平化一层
const result = arr.flat();
console.log(result); // [1, 2, 3, 4, 5, 6]

控制深度

如果数组嵌套更深,可以传入参数指定深度。

const deepArr = [1, [2, [3, [4]]]];

console.log(deepArr.flat()); // [1, 2, [3, [4]]]       (默认深度 1)
console.log(deepArr.flat(2)); // [1, 2, 3, [4]]         (深度 2)
console.log(deepArr.flat(Infinity)); // [1, 2, 3, 4]      (无限深度,完全扁平)

优点

  • 语法极简,语义清晰。
  • 支持自定义深度。
  • 自动跳过空位(sparse arrays)。

注意

  • 兼容性:IE 不支持。如果需要支持 IE,请使用 Babel 转译或下面的其他方法。

2. 经典方案:concat + spread

flat() 出现之前,这是最常用的“一行代码”解法,适用于仅有一层嵌套的二维数组。

代码实现

利用 Array.prototype.concat() 可以接受多个参数或数组作为参数的特性,结合展开运算符 ...

const arr = [
  [1, 2],
  [3, 4],
  [5, 6],
];

// 方法 A: 使用 apply (旧式写法)
const resultA = [].concat.apply([], arr);

// 方法 B: 使用 Spread 运算符 (推荐,更现代)
const resultB = [].concat(...arr);

console.log(resultB); // [1, 2, 3, 4, 5, 6]

局限性

3. 通用方案:reduce 累加器

reduce 是数组处理的神器,它可以灵活地构建任何结构。对于二维数组,我们可以用 reduce 配合 concat 来实现。

代码实现

const arr = [
  [1, 2],
  [3, 4],
  [5, 6],
];

const result = arr.reduce((acc, cur) => {
  return acc.concat(cur);
}, []);

console.log(result); // [1, 2, 3, 4, 5, 6]

进阶:配合 Spread

const result = arr.reduce((acc, cur) => [...acc, ...cur], []);

注意[...acc, ...cur] 每次都会创建新数组,性能比 acc.concat(cur) 差,建议优先使用 concat

与 flat() 对比

4. 递归方案:处理任意深度嵌套

如果数据层级不确定(可能是三维、四维甚至更深),或者你需要兼容旧环境且不能使用 flat(Infinity),则需要使用递归

代码实现

function flattenDeep(arr) {
  let result = [];

  arr.forEach((item) => {
    if (Array.isArray(item)) {
      // 如果是数组,递归调用
      result = result.concat(flattenDeep(item));
    } else {
      // 如果不是数组,直接加入
      result.push(item);
    }
  });

  return result;
}

// 测试
const deepArr = [1, [2, [3, [4, 5]]], 6];
console.log(flattenDeep(deepArr)); // [1, 2, 3, 4, 5, 6]

优化版:使用 reduce + 递归

function flattenDeep(arr) {
  return arr.reduce((acc, val) => {
    return acc.concat(Array.isArray(val) ? flattenDeep(val) : val);
  }, []);
}

优点

  • 兼容所有环境。
  • 逻辑清晰,易于理解。

注意

  • 递归过深可能导致栈溢出。对于极深层级的数据,建议使用**栈(Stack)**实现的迭代方式。

5. 选型指南与性能对比

方法适用场景兼容性性能推荐指数
flat()现代项目首选,代码简洁ES2019+ (需 Polyfill for IE)⭐⭐⭐⭐🌟🌟🌟🌟🌟
concat(...arr)确定只有一层嵌套,且数据量不大ES6+⭐⭐⭐🌟🌟🌟
reduce + concat需要兼容旧浏览器,且只有一层嵌套ES5+⭐⭐⭐⭐🌟🌟🌟🌟
递归/迭代层级不确定,或需自定义过滤逻辑所有环境⭐⭐ (递归有开销)🌟🌟🌟

最佳实践建议

  1. 日常开发:直接使用 arr.flat()。如果需要考虑 IE,引入 core-js 等 Polyfill 库即可。
  2. 高性能要求:如果数组非常大(百万级),避免使用 reduce 配合展开运算符 [...acc, ...item],因为它会频繁创建新数组。推荐使用 flat() 或传统的 for 循环 + push
  3. 复杂逻辑:如果在扁平化的同时需要过滤数据或转换格式,reduce 是最灵活的选择。
// 示例:扁平化并只保留偶数
const arr = [
  [1, 2],
  [3, 4],
  [5, 6],
];
const evenNumbers = arr.flat().filter((n) => n % 2 === 0);
// [2, 4, 6]

总结

掌握这些方法,你就能从容应对任何数组嵌套场景。记住,工具没有好坏,只有适不适合。在现代 Vue/React 项目中,请放心拥抱 flat()

以上就是JavaScript数组降维之将二维数组转为一维数组的五种方案的详细内容,更多关于JavaScript二维数组转为一维数组的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文