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

JavaScript数组分组转换求助:将含type字段数组转为指定结构

分组转换数组结构问题

输入数据

const input = [{  
  "type": "group1@action1",  
  "label": "labelA",  
  "placeholders": ["b", "a", "r"]
}, {  
  "type": "group1@action2",  
  "label": "labelB",  
  "placeholders": ["x", "y", "z"]
}, {  
  "type": "group2@action123",  
  "label": "labelC",  
  "placeholders": ["a", "b", "c"]
}];

期望输出

[  
  {  
    "group": "group1",  
    "items": [  
      {  
        "action": "action1",  
        "label": "labelA",  
        "placeholders": ["b", "a", "r"]  
      },  
      {  
        "action": "action2",  
        "label": "labelB",  
        "placeholders": ["x", "y", "z"]  
      }  
    ]  
  },  
  {  
    "group": "group2",  
    "items": [  
      {  
        "action": "action123",  
        "label": "labelC",  
        "placeholders": ["a", "b", "c"]  
      }  
    ]  
  }
]

尝试的代码及问题

字符串分割代码

var key = "group1@action1";
console.log(key.substring(0,key.indexOf('@')));
console.log(key.substring(key.indexOf('@')-1, key.length));

这里截取action的逻辑错误,indexOf('@')-1会取到@前的字符,导致结果错误。

Map实现的分组代码

output = new Map;
input.forEach(element => {
    group = element.type.substring(0,element.type.indexOf('@'));
    action = element.type.substring(element.type.indexOf('@')-1, element.type.length)
    if (!output.has(group)) {
        output.set(group, [element]);
    } else {
        output.get(group).push(element);
    }
});
console.log(output);

实际得到的Map结果

Map(2) {  
  'group1' => [  
    { type: 'group1@action1', label: 'labelA', placeholders: [Array] },  
    { type: 'group1@action2', label: 'labelB', placeholders: [Array] }  
  ],  
  'group2' => [  
    {  
      type: 'group2@action123',  
      label: 'labelC',  
      placeholders: [Array]  
    }  
  ]
}

使用Object.fromEntries(output)后的结果

{  
  group1: [{  
  label: "labelA",  
  placeholders: ["b", "a", "r"],  
  type: "group1@action1"
}, {  
  label: "labelB",  
  placeholders: ["x", "y", "z"],  
  type: "group1@action2"
}],  
  group2: [{  
  label: "labelC",  
  placeholders: ["a", "b", "c"],  
  type: "group2@action123"
}]
}

解决方案

修正后的代码

const input = [{  
  "type": "group1@action1",  
  "label": "labelA",  
  "placeholders": ["b", "a", "r"]
}, {  
  "type": "group1@action2",  
  "label": "labelB",  
  "placeholders": ["x", "y", "z"]
}, {  
  "type": "group2@action123",  
  "label": "labelC",  
  "placeholders": ["a", "b", "c"]
}];

const result = Object.values(input.reduce((acc, item) => {
  // 分割group和action,比substring更简洁可靠
  const [group, action] = item.type.split('@');
  // 初始化分组结构
  if (!acc[group]) {
    acc[group] = { group, items: [] };
  }
  // 构造符合要求的item对象,添加到分组的items数组中
  acc[group].items.push({
    action,
    label: item.label,
    placeholders: item.placeholders
  });
  return acc;
}, {}));

console.log(result);

代码说明

  1. 字符串分割:用split('@')直接拆分type字段,避免手动计算索引的错误,直接得到group和action。
  2. 分组构建:通过reduce遍历数组,以group为键存储分组结构,每个分组包含group名称和items数组。
  3. 结构转换:遍历每个item时,生成新的对象(移除原type字段,添加action字段),并推入对应分组的items数组。
  4. 结果转换:最后用Object.values将分组对象转换为期望的数组格式。

内容的提问来源于stack exchange,提问作者Stéphane GRILLON

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 17:37:46