TypeScript如何将扁平化数据库查询结果转换为层级嵌套对象结构
问题描述
我有如下数据库查询结果,原始数据展示如下:
输入数据
const input = [ { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_id: '44edfd7f-bc9e-4155-ad5c-5dace9c7c31a', ProductStock_id: '0a701dbc-2661-4d67-b764-632cfb67334f', }, { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_id: '44edfd7f-bc9e-4155-ad5c-5dace9c7c31a', ProductStock_id: '15278807-794a-4727-9bcb-f7f68dfb4d41', }, { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_id: '44edfd7f-bc9e-4155-ad5c-5dace9c7c31a', ProductStock_id: '0ac9fcd7-73f0-47b1-8fbc-3948863e7a89', }, { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_id: '65e013a7-c7b2-47cf-88b7-2ab2d9bcd191', ProductStock_id: null, }, { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_id: '8f00dde6-2548-46a7-a480-37e86a3ca895', ProductStock_id: '1439dde4-d184-4c98-b0c4-6d3c88ce8496', }, { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_id: 'b48711b3-14b1-41ce-9f5f-4032297c1b8e', ProductStock_id: null, }, { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_id: '4e22378d-cf56-4806-bea2-5ba0b220d3eb', ProductStock_id: null, }, ];
预期输出格式
const output = [ { PurchaseInvoice_id: '8e54a096-568b-48d9-8461-826be53a32da', PurchaseInvoicePosition_ids: [ { PurchaseInvoicePosition_id: '44edfd7f-bc9e-4155-ad5c-5dace9c7c31a', ProductStock_ids: [ { ProductStock_id: '0a701dbc-2661-4d67-b764-632cfb67334f', }, { ProductStock_id: '15278807-794a-4727-9bcb-f7f68dfb4d41', }, { ProductStock_id: '0ac9fcd7-73f0-47b1-8fbc-3948863e7a89', }, ], }, { PurchaseInvoicePosition_id: '65e013a7-c7b2-47cf-88b7-2ab2d9bcd191', ProductStock_ids: [ { ProductStock_id: null, }, ], }, { PurchaseInvoicePosition_id: '8f00dde6-2548-46a7-a480-37e86a3ca895', ProductStock_ids: [ { ProductStock_id: '1439dde4-d184-4c98-b0c4-6d3c88ce8496', }, ], }, { PurchaseInvoicePosition_id: 'b48711b3-14b1-41ce-9f5f-4032297c1b8e', ProductStock_ids: [ { ProductStock_id: null, }, ], }, { PurchaseInvoicePosition_id: '4e22378d-cf56-4806-bea2-5ba0b220d3eb', ProductStock_ids: [ { ProductStock_id: null, }, ], }, ], }, ];
折叠后的输出效果如下图所示:
我日常主要做PHP开发,对JavaScript相关操作不熟悉,曾尝试多次遍历输入对象、在数组中搜索匹配UUID的方式实现,但都没有成功。另外输入数据中可能包含多个不同的PurchaseInvoice_id,每个PurchaseInvoice_id关联多个PurchaseInvoicePosition_id,每个PurchaseInvoicePosition_id又关联多个ProductStock_id,求正确的实现方法。
实现代码
该实现通过两层Map做缓存实现O(n)时间复杂度的分组,支持任意数量的不同发票ID、行项ID的场景:
function transformData(input) { const result = []; // 存储发票ID对应的发票对象 const invoiceCache = new Map(); // 存储 发票ID:行项ID 对应的行项对象,避免不同发票下相同行项ID冲突 const positionCache = new Map(); for (const item of input) { const invoiceId = item.PurchaseInvoice_id; const positionId = item.PurchaseInvoicePosition_id; // 处理发票层级分组 if (!invoiceCache.has(invoiceId)) { const invoiceItem = { PurchaseInvoice_id: invoiceId, PurchaseInvoicePosition_ids: [] }; invoiceCache.set(invoiceId, invoiceItem); result.push(invoiceItem); } const currentInvoice = invoiceCache.get(invoiceId); // 处理行项层级分组 const positionKey = `${invoiceId}:${positionId}`; if (!positionCache.has(positionKey)) { const positionItem = { PurchaseInvoicePosition_id: positionId, ProductStock_ids: [] }; positionCache.set(positionKey, positionItem); currentInvoice.PurchaseInvoicePosition_ids.push(positionItem); } const currentPosition = positionCache.get(positionKey); // 插入库存ID currentPosition.ProductStock_ids.push({ ProductStock_id: item.ProductStock_id }); } return result; } // 调用示例 const output = transformData(input); console.log(output);
内容的提问来源于stack exchange,提问作者sanneo
相关产品推荐
相关产品推荐

