
本文介绍如何将多个结构相同的二维数组(每项以唯一键如数字或 date 开头)高效合并为一个新数组,使相同键的行横向聚合,适用于时间序列对齐、多源数据整合等场景。
本文介绍如何将多个结构相同的二维数组(每项以唯一键如数字或 date 开头)高效合并为一个新数组,使相同键的行横向聚合,适用于时间序列对齐、多源数据整合等场景。
在实际开发中,常需将来自不同来源但共享同一主键(如用户 ID、时间戳或 Date 对象)的二维数组进行横向合并。例如,三组传感器数据分别记录了同一时间点的温度、湿度和光照强度,需按时间对齐合并成单条记录。原始方案使用 Map 手动归集已具备良好可读性与兼容性,但存在优化空间——尤其当键为 Date 对象时,需注意其引用相等性问题(new Date(2024,0,1) !== new Date(2024,0,1)),而原代码未作标准化处理。
以下提供两种专业级解决方案:
✅ 推荐方案:原生 JavaScript(健壮 & 无依赖)
function mergeArrays(arrays) {
// 使用字符串化 Date 作为 key(适配 Date 类型)
const getKey = (item) => {
const key = item[0];
return key instanceof Date ? key.toISOString() : key;
};
const mergedMap = new Map();
for (const array of arrays) {
for (const item of array) {
const key = getKey(item);
if (!mergedMap.has(key)) {
mergedMap.set(key, [item[0]]); // 保留原始 key(非字符串化值)
}
mergedMap.get(key).push(...item.slice(1));
}
}
return Array.from(mergedMap.values());
}
// 示例调用(支持 Date 键)
const arr1 = [[new Date('2024-01-01'), 'A'], [new Date('2024-01-02'), 'B']];
const arr2 = [[new Date('2024-01-01'), 'D'], [new Date('2024-01-02'), 'E']];
const arr3 = [[new Date('2024-01-01'), 'G'], [new Date('2024-01-02'), 'H']];
console.log(mergeArrays([arr1, arr2, arr3]));
// → [[Mon Jan 01 2024..., 'A', 'D', 'G'], [Tue Jan 02 2024..., 'B', 'E', 'H']]
⚠️ 注意事项
- Date 键必须标准化:直接用 Date 对象作 Map 键会因引用不同导致合并失败,务必统一转换为 toISOString() 或 getTime();
-
顺序保证:Map 迭代顺序与插入顺序一致,若需按时间升序输出,最后应显式排序:
return Array.from(mergedMap.values()).sort((a, b) => new Date(a[0]) - new Date(b[0]) );
- 去重需求? 原始需求未要求去重;若需避免重复值(如 'A' 出现多次),可在 push 后加 filter((v, i, a) => a.indexOf(v) === i),但会影响性能。
? Lodash 方案(简洁但有取舍)
Lodash 版本代码更简短,但 _.groupBy 默认使用 === 比较键——对 Date 对象仍会失效;且 _.uniq(_.flatten(L1)) 会扁平化并去重所有值(含非首列),可能误删有效重复数据(如多传感器同值)。因此不推荐用于 Date 键或允许重复值的业务场景。
✅ 总结:优先使用增强版原生方案——它明确处理 Date 键、保留原始数据结构、零依赖、易于调试与维护。仅当项目已深度集成 Lodash 且键均为基础类型(string/number)时,才考虑链式写法。











