You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中转换/扁平化包含数组的对象数组?

TypeScript 实现时间序列数据结构转换

需求说明

原始数据按「图层(layer)」分组,每个图层下包含多条带时间戳的数值记录;需要将其转换为按「时间戳(timestamp)」聚合的结构,每个时间戳条目包含所有图层对应的数值。

原始数据结构:

{"layers": [{"layer": "foo","values": [{"timestamp": "1970-01-01T00:00:00Z","value": 0},{"timestamp": "1970-01-01T01:00:00Z","value": 0},{"timestamp": "1970-01-01T02:00:00Z","value": 0},{"timestamp": "1970-01-01T03:00:00Z","value": 0}]},{"layer": "bar","values": [{"timestamp": "1970-01-01T00:00:00Z","value": 1},{"timestamp": "1970-01-01T01:00:00Z","value": 1},{"timestamp": "1970-01-01T02:00:00Z","value": 1},{"timestamp": "1970-01-01T03:00:00Z","value": 1}]}]}

目标数据结构:

[{"timestamp": "1970-01-01T00:00:00Z","foo": 0,"bar": 1},{"timestamp": "1970-01-01T01:00:00Z","foo": 0,"bar": 1},{"timestamp": "1970-01-01T02:00:00Z","foo": 0,"bar": 1},{"timestamp": "1970-01-01T03:00:00Z","foo": 0,"bar": 1}]

实现方案

1. 定义类型(TypeScript 类型约束)

先为原始数据和目标数据定义接口,确保类型安全:

// 原始数据的单条数值记录
interface RawValue {
  timestamp: string;
  value: number;
}

// 原始数据的图层结构
interface RawLayer {
  layer: string;
  values: RawValue[];
}

// 原始数据整体结构
interface RawData {
  layers: RawLayer[];
}

// 转换后的单条记录类型(动态键对应图层名称)
type TransformedRecord = {
  timestamp: string;
} & Record<string, number>;

2. 转换函数实现

核心思路是用 Map 按时间戳聚合所有图层的数值,最后将 Map 转换为数组:

function transformData(rawData: RawData): TransformedRecord[] {
  // 用 Map 存储每个时间戳对应的聚合结果
  const timestampMap = new Map<string, TransformedRecord>();

  // 遍历每个图层
  rawData.layers.forEach(({ layer, values }) => {
    // 遍历当前图层的所有数值记录
    values.forEach(({ timestamp, value }) => {
      // 如果 Map 中已有该时间戳的条目,直接添加当前图层的键值对
      if (timestampMap.has(timestamp)) {
        const existingRecord = timestampMap.get(timestamp)!;
        existingRecord[layer] = value;
      } else {
        // 没有则创建新条目,初始化时间戳和当前图层的数值
        timestampMap.set(timestamp, {
          timestamp,
          [layer]: value
        });
      }
    });
  });

  // 将 Map 的值转换为数组并返回
  return Array.from(timestampMap.values());
}

3. 使用示例

// 原始数据示例
const inputData: RawData = {
  "layers": [
    {"layer": "foo","values": [{"timestamp": "1970-01-01T00:00:00Z","value": 0},{"timestamp": "1970-01-01T01:00:00Z","value": 0},{"timestamp": "1970-01-01T02:00:00Z","value": 0},{"timestamp": "1970-01-01T03:00:00Z","value": 0}]},
    {"layer": "bar","values": [{"timestamp": "1970-01-01T00:00:00Z","value": 1},{"timestamp": "1970-01-01T01:00:00Z","value": 1},{"timestamp": "1970-01-01T02:00:00Z","value": 1},{"timestamp": "1970-01-01T03:00:00Z","value": 1}]}
  ]
};

// 执行转换
const outputData = transformData(inputData);
console.log(outputData);
// 输出结果与目标结构一致

关键说明

  • 使用 Map 可以高效按时间戳去重和聚合,避免重复遍历数组
  • 动态属性 [layer] 用于将图层名称作为对象的键,适配任意图层名称
  • 类型定义确保了输入输出的类型安全,减少运行时错误

内容的提问来源于stack exchange,提问作者mrt181

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:31:09