如何处理JSON数据,将属性值相同的对象合并并把重复项存入数组
实现方案
你可以通过以下两种方式实现需求,分别是基于lodash的实现和原生JavaScript无依赖实现:
基于lodash的实现(适配你提到的groupBy方法)
核心逻辑是用三个字段拼接成分组key,对数组分组后处理每个分组的元素:
const _ = require('lodash'); // 你的原始数据 const rawData = [ {createdAt: "2021-09-09 07:37", user_id: "admin", type: "click", query: "spider"}, {createdAt: "2021-09-09 07:37", user_id: "admin", type: "search", query: "spider"}, {createdAt: "2021-09-09 07:38", user_id: "user", type: "click", query: "hi"}, ]; const result = _.chain(rawData) // 按三个字段拼接的key分组 .groupBy(item => `${item.createdAt}|${item.user_id}|${item.query}`) // 处理每个分组 .map(group => { // 第一个元素作为主对象 const mainItem = group[0]; if (group.length > 1) { // 剩余元素存入result数组 mainItem.result = group.slice(1); } return mainItem; }) .value();
打印result即可得到你需要的目标结构。
原生JavaScript实现(无需引入第三方库)
如果不想引入lodash,可以用普通对象做分组缓存,一次遍历完成处理:
const rawData = [ {createdAt: "2021-09-09 07:37", user_id: "admin", type: "click", query: "spider"}, {createdAt: "2021-09-09 07:37", user_id: "admin", type: "search", query: "spider"}, {createdAt: "2021-09-09 07:38", user_id: "user", type: "click", query: "hi"}, ]; const groupMap = {}; const result = []; rawData.forEach(item => { const key = `${item.createdAt}|${item.user_id}|${item.query}`; if (!groupMap[key]) { // 第一次出现该key,作为主对象存入结果和缓存 groupMap[key] = item; result.push(item); } else { // 已存在的key,将当前项存入主对象的result数组 if (!groupMap[key].result) groupMap[key].result = []; groupMap[key].result.push(item); } });
注意:如果你的字段值可能包含
|字符,可以把分组key替换为JSON.stringify([item.createdAt, item.user_id, item.query]),避免key重复冲突。
内容的提问来源于stack exchange,提问作者Kuno Kim
相关产品推荐
相关产品推荐

