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

如何用JavaScript的reduce或forEach实现指定数据格式转换?

嘿,我来帮你搞定这个格式转换的问题!你需要把相同日期的记录合并,把不同的作业类型(assignment)作为属性放到同一个日期对象里对吧?下面我用JavaScript原生的reduce、forEach,还有你提到的lodash方法分别实现,都是符合你期望的输出格式的:

1. 使用reduce实现(推荐方案)

reduce是处理这类分组合并场景最顺手的原生方法,它可以帮我们累积结果,避免额外的变量声明:

const data = [
  { date: '2018-01-08', assignment: 'java', count: 2 },
  { date: '2018-01-04', assignment: 'java', count: 3 },
  { date: '2018-01-04', assignment: 'javaScript', count: 2 },
  { date: '2017-12-18', assignment: 'java', count: 2 },
  { date: '2017-11-24', assignment: 'java', count: 2 },
  { date: '2018-01-02', assignment: 'javaScript', count: 2 }
];

const formattedData = Object.values(data.reduce((accumulator, currentItem) => {
  // 如果累加器里还没有当前日期的对象,就初始化一个带date属性的空对象
  if (!accumulator[currentItem.date]) {
    accumulator[currentItem.date] = { date: currentItem.date };
  }
  // 将当前作业类型作为属性,计数作为值赋值到对应日期对象中
  accumulator[currentItem.date][currentItem.assignment] = currentItem.count;
  return accumulator;
}, {}));

console.log(formattedData);

逻辑说明:

  • 我们用一个空对象作为reduce的初始累加器,键是日期字符串,值是对应合并后的对象
  • 遍历每个数据项时,先检查累加器中是否存在当前日期的对象,不存在就创建一个
  • 把当前项的assignment作为属性名,count作为属性值添加到该日期对象中
  • 最后用Object.values()把累加器中的所有值提取成数组,就是你要的最终格式

2. 使用forEach实现

如果你更喜欢更直观的遍历方式,forEach也能实现,核心逻辑和reduce一致,只是手动维护累加对象和结果数组:

const data = [/* 你的原始数据 */];
const dateMap = {};
const formattedData = [];

data.forEach(item => {
  // 如果当前日期还没被处理过,创建新对象并加入结果数组
  if (!dateMap[item.date]) {
    const newDateObj = { date: item.date };
    dateMap[item.date] = newDateObj;
    formattedData.push(newDateObj);
  }
  // 给对应日期对象添加作业计数属性
  dateMap[item.date][item.assignment] = item.count;
});

console.log(formattedData);

逻辑说明:

  • dateMap用来记录每个日期对应的对象引用,避免重复创建
  • 遇到新日期时,创建对象并同时存入dateMap和结果数组
  • 后续同日期的项直接通过dateMap找到对应对象,添加属性即可

3. 使用Lodash实现(结合你提到的groupBy)

如果你已经在项目中使用Lodash,可以用groupBy先按日期分组,再对每组进行合并:

const _ = require('lodash');

const data = [/* 你的原始数据 */];
const formattedData = _.chain(data)
  .groupBy('date') // 先按日期分组,得到以日期为键的对象
  .mapValues(group => {
    // 对每组数据进行合并,初始化带日期的对象后,逐个添加作业属性
    return group.reduce((mergedObj, item) => {
      mergedObj[item.assignment] = item.count;
      return mergedObj;
    }, { date: group[0].date });
  })
  .values() // 提取所有分组后的对象为数组
  .value();

console.log(formattedData);

这样几种方式都能得到你期望的输出格式,其中reduce方案最简洁高效,推荐优先使用~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:27:17