JavaScript中如何基于对象数组相同匹配项计算不同日期val属性差值
实现代码
下面是可直接运行、复用性高的封装函数:
/** * 计算两个日期同分组数据的属性差值 * @param {Array} arr 原始数据数组 * @param {String} groupKey 分组依据的属性名,默认按site分组 * @param {String} baseDate 被减的基准日期 * @param {String} compareDate 减去基准的对比日期 * @param {Array} calcKeys 需要计算差值的属性列表 * @returns {Array} 计算后的结果数组 */ function calcValDiff(arr, groupKey = 'site', baseDate = '2020-05-01', compareDate = '2020-05-03', calcKeys = ['val1', 'val2', 'val3']) { // 构建日期-分组映射表,方便快速取值 const dateMap = {}; arr.forEach(item => { const groupVal = item[groupKey]; if (!dateMap[item.date]) dateMap[item.date] = {}; dateMap[item.date][groupVal] = item; }); const result = []; const baseDataMap = dateMap[baseDate] || {}; // 遍历所有分组计算差值 for (const groupVal in baseDataMap) { const baseItem = baseDataMap[groupVal]; const compareItem = dateMap[compareDate]?.[groupVal]; // 仅当两个日期都存在对应分组数据时才计算 if (compareItem) { const resItem = { device: baseItem.device, [groupKey]: groupVal }; calcKeys.forEach(key => { resItem[key] = compareItem[key] - baseItem[key]; }); result.push(resItem); } } return result; } // 调用示例 // 注:你提供的原始输入两天val完全一致,为匹配给出的预期输出,已调整2020-05-03的val数值 let data = [ {date:'2020-05-01', device: 'iphone', site: 'google', val1:10, val2:20, val3:30}, {date:'2020-05-01', device: 'iphone', site: 'bing', val1:23, val2:12, val3:14}, {date:'2020-05-01', device: 'iphone', site: 'jeeves', val1:67, val2:78, val3:12}, {date:'2020-05-03', device: 'iphone', site: 'google', val1:5, val2:25, val3:45}, {date:'2020-05-03', device: 'iphone', site: 'bing', val1:33, val2:2, val3:67}, {date:'2020-05-03', device: 'iphone', site: 'jeeves', val1:77, val2:99, val3:25} ]; console.log(calcValDiff(data));
逻辑说明
- 先把原始数据按日期、分组键构建双层映射,不需要循环多次匹配数据,时间复杂度为O(n)
- 所有可变参数都做了可配置默认值,需要调整分组维度、对比日期、计算属性时直接传参即可,不需要修改函数内部逻辑
- 自动过滤两个日期不同时存在的分组数据,避免运行报错
内容的提问来源于stack exchange,提问作者nb_nb_nb
相关产品推荐
相关产品推荐

