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

如何用TypeScript/JavaScript将扁平JSON转为问卷层级结构?可借助Lodash吗?

如何用Lodash将扁平JSON转换为问卷层级结构?

我有一份扁平JSON数据,需要使用TypeScript/JavaScript将其转换为层级结构,用于后续构建问卷。想知道是否可以用Lodash或类似库实现这个转换?

TypeScript类定义

export class Template
{
    template_id: number;
    template_name: string;
    sections: Section[];
}

export class Section
{
    section_id: number;
    section_name: string;
    fields: Field[];
}

export class Field
{
    field_id: number;
    field_lable : string;
    input_type: InputType;
}

export class InputType
{
    input_type_id: number;
    input_type_name: string;
}

扁平数据示例(最终需转换为Template数组)

[
   {
      "Template_id":1,
      "Template_Name":"Enterprise",
      "Section_id":1,
      "Section_Name":"Basic Info",
      "Field_id":1,
      "Field_Label":"Enter Your Name",
      "Input_Type_id":1,
      "Input_Type_Name":"Text"
   },
   {
      "Template_id":1,
      "Template_Name":"Enterprise",
      "Section_id":1,
      "Section_Name":"Basic Info",
      "Field_id":2,
      "Field_Label":"Enter Your Address",
      "Input_Type_id":1,
      "Input_Type_Name":"Text"
   },
   {
      "Template_id":1,
      "Template_Name":"Enterprise",
      "Section_id":2,
      "Section_Name":"Environment",
      "Field_id":3,
      "Field_Label":"Do you believe in environment",
      "Input_Type_id":3,
      "Input_Type_Name":"Checkbox"
   },
   {
      "Template_id":1,
      "Template_Name":"Enterprise",
      "Section_id":3,
      "Section_Name":"Transfer",
      "Field_id":4,
      "Field_Label":"Select prefer transfer modes",
      "Input_Type_id":2,
      "Input_Type_Name":"Dropdown"
   },
   {
      "Template_id":2,
      "Template_Name":"RRR",
      "Section_id":4,
      "Section_Name":"Basic Info",
      "Field_id":5,
      "Field_Label":"Enter Your Name",
      "Input_Type_id":1,
      "Input_Type_Name":"Text"
   },
   {
      "Template_id":2,
      "Template_Name":"RRR",
      "Section_id":4,
      "Section_Name":"Basic Info",
      "Field_id":6,
      "Field_Label":"Enter Your Address",
      "Input_Type_id":1,
      "Input_Type_Name":"Text"
   },
   {
      "Template_id":2,
      "Template_Name":"RRR",
      "Section_id":5,
      "Section_Name":"GPO",
      "Field_id":7,
      "Field_Label":"Select names of GPOs",
      "Input_Type_id":2,
      "Input_Type_Name":"Dropdown"
   },
   {
      "Template_id":2,
      "Template_Name":"RRR",
      "Section_id":6,
      "Section_Name":"Unit",
      "Field_id":8,
      "Field_Label":"Enter name of your unit",
      "Input_Type_id":1,
      "Input_Type_Name":"Text"
   }
]

期望输出

[
   {
      "Template_id":1,
      "Template_Name":"Enterprise",
      "Sections":[
         {
            "Section_id":1,
            "Section_Name":"Basic Info",
            "Fields":[
               {
                  "Field_id":1,
                  "Field_Label":"Enter Your Name",
                  "Input_Type_id":1,
                  "Input_Type_Name":"Text"
               },
               {
                  "Field_id":2,
                  "Field_Label":"Enter Your Address",
                  "Input_Type_id":1,
                  "Input_Type_Name":"Text"
               }
            ]
         },
         {
            "Section_id":2,
            "Section_Name":"Environment",
            "Fields":[
               {
                  "Field_id":3,
                  "Field_Label":"Do you believe in environment",
                  "Input_Type_id":3,
                  "Input_Type_Name":"Checkbox"
               }
            ]
         }
      ]
   },
   {
      "Template_id":2,
      "Template_Name":"RRR",
      "Sections":[
         {
            "Section_id":4,
            "Section_Name":"Basic Info",
            "Fields":[
               {
                  "Field_id":5,
                  "Field_Label":"Enter Your Name",
                  "Input_Type_id":1,
                  "Input_Type_Name":"Text"
               },
               {
                  "Field_id":6,
                  "Field_Label":"Enter Your Address",
                  "Input_Type_id":1,
                  "Input_Type_Name":"Text"
               }
            ]
         },
         {
            "Section_id":5,
            "Section_Name":"GPO",
            "Fields":[
               {
                  "Field_id":7,
                  "Field_Label":"Select names of GPOs",
                  "Input_Type_id":2,
                  "Input_Type_Name":"Dropdown"
               }
            ]
         }
      ]
   }
]

解决方案

用Lodash实现

Lodash的groupBy方法可以快速完成分组,再逐层组装层级结构:

import _ from 'lodash';

// 定义扁平数据的类型
interface FlatDataItem {
  Template_id: number;
  Template_Name: string;
  Section_id: number;
  Section_Name: string;
  Field_id: number;
  Field_Label: string;
  Input_Type_id: number;
  Input_Type_Name: string;
}

// 定义输出结构的类型
interface TemplateOutput {
  Template_id: number;
  Template_Name: string;
  Sections: {
    Section_id: number;
    Section_Name: string;
    Fields: Omit<FlatDataItem, 'Template_id' | 'Template_Name' | 'Section_id' | 'Section_Name'>[];
  }[];
}

function transformFlatData(flatData: FlatDataItem[]): TemplateOutput[] {
  // 第一步:按Template_id分组
  const groupedByTemplate = _.groupBy(flatData, 'Template_id');
  
  return Object.values(groupedByTemplate).map(templateItems => {
    // 提取模板的基础信息
    const { Template_id, Template_Name } = templateItems[0];
    // 第二步:在当前模板组内按Section_id分组
    const groupedBySection = _.groupBy(templateItems, 'Section_id');
    
    // 组装章节数组
    const sections = Object.values(groupedBySection).map(sectionItems => {
      const { Section_id, Section_Name } = sectionItems[0];
      // 提取字段信息,去除冗余字段
      const fields = sectionItems.map(item => ({
        Field_id: item.Field_id,
        Field_Label: item.Field_Label,
        Input_Type_id: item.Input_Type_id,
        Input_Type_Name: item.Input_Type_Name
      }));
      
      return { Section_id, Section_Name, Fields: fields };
    });
    
    return { Template_id, Template_Name, Sections: sections };
  });
}

原生JavaScript实现(无需Lodash)

如果不想引入第三方库,用原生reduce方法也能实现相同逻辑:

function transformFlatDataNative(flatData: FlatDataItem[]): TemplateOutput[] {
  return flatData.reduce((templates, item) => {
    // 查找或创建当前模板
    let template = templates.find(t => t.Template_id === item.Template_id);
    if (!template) {
      template = {
        Template_id: item.Template_id,
        Template_Name: item.Template_Name,
        Sections: []
      };
      templates.push(template);
    }
    
    // 查找或创建当前章节
    let section = template.Sections.find(s => s.Section_id === item.Section_id);
    if (!section) {
      section = {
        Section_id: item.Section_id,
        Section_Name: item.Section_Name,
        Fields: []
      };
      template.Sections.push(section);
    }
    
    // 添加字段到章节
    section.Fields.push({
      Field_id: item.Field_id,
      Field_Label: item.Field_Label,
      Input_Type_id: item.Input_Type_id,
      Input_Type_Name: item.Input_Type_Name
    });
    
    return templates;
  }, [] as TemplateOutput[]);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:27:39