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

TypeScript如何合并对象数组中关联状态数组生成新数组?

问题描述

现有如下TypeScript数组:

const books = [
    {
        name: 'book1',
        id: '1',
        fromStatus: [
            { name: 'Available', id: 1 },
            { name: 'Free', id: 2 }
        ],
        toStatus: [
            { name: 'Not available', id: 1 },
            { name: 'Not free', id: 2 }
        ]
    },
    {
        name: 'book2',
        id: '2',
        fromStatus: [{ name: 'Burnt', id: 1 }],
        toStatus: [{ name: 'Not burnt', id: 1 }]
    }
];

需要生成新数组,根据id匹配每个fromStatus和对应的toStatus,整合为包含id、fromStatusName、toStatusName的新对象,目标数组如下:

const statusFromTo = [
    {
        id: 1,
        fromStatusName: 'Available',
        toStatusName: 'Not available'
    },
    {
        id: 2,
        fromStatusName: 'Burnt',
        toStatusName: 'Not burnt'
    },
    {
        id: 3,
        fromStatusName: 'Free',
        toStatusName: 'Not free'
    }
];
解决方案

可以通过状态映射收集+数组转换的方式实现,代码如下:

// 收集所有状态的映射关系,避免重复
const statusMap = new Map<number, { fromName: string; toName: string }>();

books.forEach(book => {
    // 把当前书籍的toStatus转成id到名称的映射,方便快速查找
    const toStatusMap = book.toStatus.reduce((acc, status) => {
        acc[status.id] = status.name;
        return acc;
    }, {} as Record<number, string>);
    
    // 遍历fromStatus,匹配对应的toStatus名称
    book.fromStatus.forEach(fromStatus => {
        const targetToName = toStatusMap[fromStatus.id];
        if (targetToName) {
            statusMap.set(fromStatus.id, {
                fromName: fromStatus.name,
                toName: targetToName
            });
        }
    });
});

// 转换为目标数组,生成自增的新id
const statusFromTo = Array.from(statusMap.entries()).map(([_, names], index) => ({
    id: index + 1,
    fromStatusName: names.fromName,
    toStatusName: names.toName
}));

逻辑说明

  1. 遍历每本书,先把当前书的toStatus转换为以id为键、状态名为值的对象,这样可以通过id直接获取对应的目标状态名,避免嵌套循环查找。
  2. 遍历当前书的fromStatus,通过id从上面的映射中拿到对应的toStatus名称,存入Map中(如果有相同原始id的状态,会自动去重)。
  3. 最后把Map中的内容转为数组,同时生成自增的新id,结构化成目标格式。

如果不需要去重(允许相同原始id的状态重复出现在结果中),可以直接收集数组:

const statusFromTo: { id: number; fromStatusName: string; toStatusName: string }[] = [];

books.forEach(book => {
    const toStatusMap = book.toStatus.reduce((acc, status) => {
        acc[status.id] = status.name;
        return acc;
    }, {} as Record<number, string>);
    
    book.fromStatus.forEach(fromStatus => {
        const targetToName = toStatusMap[fromStatus.id];
        if (targetToName) {
            statusFromTo.push({
                id: statusFromTo.length + 1,
                fromStatusName: fromStatus.name,
                toStatusName: targetToName
            });
        }
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:40:32