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

基于子数组字段的JOLT数据分组转换需求

问题:按levelOne和levelTwo对JSON数据分层分组

需要将给定的JSON数据,按照子对象中的levelOne和levelTwo字段进行两级分组,转换成更适合UI展示的层级结构。

输入数据

{
  "id": "101",
  "myLevel": "Beginner",
  "riskProducts": [
    {
      "id": "1",
      "product": {
        "id": "2",
        "levelOne": "Equities",
        "levelTwo": "Global Developed Large Cap Equity",
        "productName": "Allianz Thematica Fund",
        "proposedAmountToInvest": "null",
        "proposedHoldings": "2",
        "unitPrice": "111.44"
      }
    },
    {
      "id": "2",
      "product": {
        "id": "1",
        "levelOne": "Equities",
        "levelTwo": "Global Developed Large Cap Equity",
        "productName": "AB Low Volatility Equity Portfolio",
        "proposedAmountToInvest": "null",
        "proposedHoldings": "2",
        "unitPrice": "150.18"
      }
    },
    {
      "id": "4",
      "product": {
        "id": "4",
        "levelOne": "Equities",
        "levelTwo": "US Large Cap Equity",
        "productName": "Franklin Technology Fund",
        "proposedAmountToInvest": "null",
        "proposedHoldings": "4",
        "unitPrice": "93.02"
      }
    },
    {
      "id": "5",
      "product": {
        "id": "5",
        "levelOne": "Fixed Income",
        "levelTwo": "Global Aggregate Bonds",
        "productName": "PIMCO GIS Income Fund HKD Inc",
        "proposedAmountToInvest": "null",
        "proposedHoldings": "7",
        "unitPrice": "11.93"
      }
    }
  ]
}

期望输出

{
  "myLevel": "Beginner",
  "levelOne": [
    {
      "id": "Equities",
      "levelTwo": [
        {
          "id": "Global Developed Large Cap Equity",
          "product": [
            {
              "id": "2",
              "productName": "Allianz Thematica Fund",
              "proposedHoldings": "2",
              "unitPrice": "111.44"
            },
            {
              "id": "1",
              "productName": "AB Low Volatility Equity Portfolio",
              "proposedHoldings": "2",
              "unitPrice": "150.18"
            }
          ],
          "sPercentage": "0",
          "tPercentage": "0"
        },
        {
          "id": "US Large Cap Equity",
          "product": [
            {
              "id": "4",
              "productName": "Franklin Technology Fund",
              "proposedHoldings": "4",
              "unitPrice": "93.02"
            }
          ],
          "sPercentage": "0",
          "tPercentage": "0"
        }
      ]
    },
    {
      "id": "Fixed Income",
      "levelTwo": [
        {
          "id": "Global Aggregate Bonds",
          "product": [
            {
              "id": "5",
              "productName": "PIMCO GIS Income Fund HKD Inc",
              "proposedAmountToInvest": "null",
              "proposedHoldings": "7",
              "unitPrice": "11.93"
            }
          ],
          "sPercentage": "0",
          "tPercentage": "0"
        }
      ]
    }
  ]
}

解决方案(JavaScript实现)

const inputData = {
  "id": "101",
  "myLevel": "Beginner",
  "riskProducts": [
    { "id": "1", "product": { "id": "2", "levelOne": "Equities", "levelTwo": "Global Developed Large Cap Equity", "productName": "Allianz Thematica Fund", "proposedAmountToInvest": "null", "proposedHoldings": "2", "unitPrice": "111.44" } },
    { "id": "2", "product": { "id": "1", "levelOne": "Equities", "levelTwo": "Global Developed Large Cap Equity", "productName": "AB Low Volatility Equity Portfolio", "proposedAmountToInvest": "null", "proposedHoldings": "2", "unitPrice": "150.18" } },
    { "id": "4", "product": { "id": "4", "levelOne": "Equities", "levelTwo": "US Large Cap Equity", "productName": "Franklin Technology Fund", "proposedAmountToInvest": "null", "proposedHoldings": "4", "unitPrice": "93.02" } },
    { "id": "5", "product": { "id": "5", "levelOne": "Fixed Income", "levelTwo": "Global Aggregate Bonds", "productName": "PIMCO GIS Income Fund HKD Inc", "proposedAmountToInvest": "null", "proposedHoldings": "7", "unitPrice": "11.93" } }
  ]
};

const transformData = (input) => {
  const result = {
    myLevel: input.myLevel,
    levelOne: []
  };
  // 用对象映射快速定位已存在的levelOne分组
  const levelOneMap = {};

  input.riskProducts.forEach(item => {
    const { levelOne, levelTwo, id, productName, proposedHoldings, unitPrice, proposedAmountToInvest } = item.product;

    // 处理一级分组:levelOne
    if (!levelOneMap[levelOne]) {
      const levelOneItem = { id: levelOne, levelTwo: [] };
      levelOneMap[levelOne] = levelOneItem;
      result.levelOne.push(levelOneItem);
    }
    const currentLevelOne = levelOneMap[levelOne];

    // 生成当前levelOne下的levelTwo映射,避免循环查找
    const levelTwoMap = currentLevelOne.levelTwo.reduce((map, item) => {
      map[item.id] = item;
      return map;
    }, {});

    // 处理二级分组:levelTwo
    if (!levelTwoMap[levelTwo]) {
      const levelTwoItem = {
        id: levelTwo,
        product: [],
        sPercentage: "0",
        tPercentage: "0"
      };
      levelTwoMap[levelTwo] = levelTwoItem;
      currentLevelOne.levelTwo.push(levelTwoItem);
    }
    const currentLevelTwo = levelTwoMap[levelTwo];

    // 提取需要的产品字段,保留可选的proposedAmountToInvest
    const productItem = {
      id,
      productName,
      proposedHoldings,
      unitPrice,
      ...(proposedAmountToInvest && { proposedAmountToInvest })
    };
    currentLevelTwo.product.push(productItem);
  });

  return result;
};

// 执行转换并打印结果
const outputData = transformData(inputData);
console.log(JSON.stringify(outputData, null, 2));

核心原理说明

  • 多级分组逻辑:通过两层分组实现,先按levelOne聚合,再在每个levelOne分组下按levelTwo聚合
  • 映射优化效率:使用对象存储已创建的分组项,避免每次查找都遍历数组,提升处理速度
  • 字段提取:仅保留UI需要的产品字段,过滤冗余数据,同时默认添加sPercentage和tPercentage字段

学习资源推荐

  • 优先看MDN中文文档的数组方法(forEach、reduce)和对象操作章节,掌握遍历与映射的基础逻辑
  • 掘金平台搜索「JavaScript多级数组分组」,有大量实战案例讲解不同场景下的分组技巧
  • 菜鸟教程的JavaScript对象与数组模块,适合巩固语法基础,理解数据结构操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:50:17