
本文讲解如何将一个“矩形”二维数组(即每行长度相等)按列切分,得到由各列组成的数组,核心是利用首行索引驱动外层遍历,避免因按行数遍历导致列缺失的问题。
本文讲解如何将一个“矩形”二维数组(即每行长度相等)按列切分,得到由各列组成的数组,核心是利用首行索引驱动外层遍历,避免因按行数遍历导致列缺失的问题。
在处理二维数组时,常需将“行优先”的数据结构转换为“列优先”视图——例如用于矩阵转置、表格列聚合或可视化库的数据预处理。但若直接对主数组(行数组)调用 .map(),其迭代次数等于行数,会导致仅能提取前 N 列(N = 行数),而忽略实际存在的更多列(如输入为 3 行 × 4 列时,错误方法只返回 3 列)。
正确思路是:以列数为基准进行外层遍历。由于矩形数组各行长度一致,可安全使用 array[0].length 获取总列数,或更简洁地——直接基于首行 array[0] 调用 .map(),利用其索引 i 去逐行提取第 i 个元素。
以下是推荐的实现方式:
const arr = [ [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4] ]; // ✅ 正确:以首行长度为列总数,i 遍历所有列索引 const columns = arr[0].map((_, i) => arr.map(row => row[i]) ); console.log(columns); // 输出: [[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]]
该方案本质是两次 map 的嵌套:
- 外层 arr[0].map(...):遍历首行的每个索引 i(即列号),确保覆盖全部列;
- 内层 arr.map(row => row[i]):对每一行提取第 i 列元素,构成新列数组。
⚠️ 注意事项:
- 前提必须是矩形数组:所有子数组长度严格相等,否则 row[i] 可能为 undefined;
- 若需健壮性处理非矩形输入,应先校验:
if (!arr.every(row => row.length === arr[0].length)) { throw new Error("Input is not a rectangular 2D array"); } - 性能上为 O(m×n) 时间复杂度(m 行,n 列),空间复杂度 O(m×n),属最优解,无可避免的全量遍历。
总结:提取二维矩形数组所有列的关键,在于将列索引作为外层遍历依据,而非依赖行数组自身长度。这一模式简洁、高效且符合函数式编程思想,适用于 JavaScript 中绝大多数数据整形场景。










