使用lodash/fp移除两个数组中重复日期对象的解决方案
解决Date对象数组的去重/合并问题
嘿,这个坑我之前踩过!你说的没错,_.uniqBy没起作用完全是因为Date对象的特性——哪怕两个Date实例代表的时间一模一样,它们也是不同的对象引用,直接用对象本身做匹配键的话,Lodash根本认不出它们是“相同”的。
那该怎么处理呢?分两种场景给你解决方案:
场景1:只需要去重,保留第一个匹配项
既然直接比Date对象不行,我们可以把Date转换成可直接比较的原始值,比如时间戳(getTime())或者ISO标准字符串(toISOString()),用这个值作为_.uniqBy的匹配键。
举个例子,假设你的数据结构是这样:
const data = [ { date: new Date(2018, 4, 7), value: 10 }, { date: new Date(2018, 4, 7), value: 20 }, { date: new Date(2018, 4, 8), value: 15 } ];
用时间戳做匹配键的代码:
const uniqueData = _.uniqBy(data, item => item.date.getTime()); // 结果会保留第一个2018-05-07的项,去掉重复的那个
用ISO字符串也可以,效果一样:
const uniqueData = _.uniqBy(data, item => item.date.toISOString());
场景2:需要合并相同日期的项(比如累加value)
如果不是单纯去重,而是要把同日期的数值合并,_.uniqBy就不够用了,这时候可以用_.groupBy先分组,再手动合并:
// 第一步:按时间戳分组,把同日期的项归到一组 const groupedData = _.groupBy(data, item => item.date.getTime()); // 第二步:遍历每组,合并数据(这里以累加value为例) const mergedData = Object.values(groupedData).map(group => ({ date: group[0].date, // 保留组里第一个Date对象即可 value: group.reduce((total, item) => total + item.value, 0) }));
不用Lodash的原生JS方案
如果你不想依赖Lodash,用原生的Map也能搞定合并:
const dateMap = new Map(); data.forEach(item => { const timestamp = item.date.getTime(); if (dateMap.has(timestamp)) { // 已存在则累加value dateMap.get(timestamp).value += item.value; } else { // 不存在则添加新项 dateMap.set(timestamp, {...item}); } }); // 把Map转换成数组 const mergedData = Array.from(dateMap.values());
核心思路就是:不要直接用Date对象做匹配依据,转成它的时间戳或字符串形式,这些原始值可以被正确比较相等性。
内容的提问来源于stack exchange,提问作者Joe Warner
相关产品推荐
相关产品推荐

