如何按日期合并两个聊天消息数组对象?
合并按日期分组的聊天消息对象
我有两个按日期分组的聊天消息数组对象,需要将二者合并为格式相同的对象,合并同一日期下的所有消息。
数据示例
const data1 = { messages: { "27-04-2023": [ { id: "SOkXFGtTwh" }, { id: "i3NrqNyG9P" }, { id: "lCmxr4rc5T" } ] } }; const data2 = { messages: { "27-04-2023": [ { id: "V9QzRgl6ji" }, { id: "K5wfD-kX8W" } ], "24-04-2023": [ { id: "tuarzhHPwH" }, { id: "cbxu_dAeAj" }, { id: "9xJpEJGUnm" } ] } };
期望输出
const mergedData = { messages: { "27-04-2023": [ { id: "SOkXFGtTwh" }, { id: "i3NrqNyG9P" }, { id: "lCmxr4rc5T" }, { id: "V9QzRgl6ji" }, { id: "K5wfD-kX8W" } ], "24-04-2023": [ { id: "tuarzhHPwH" }, { id: "cbxu_dAeAj" }, { id: "9xJpEJGUnm" } ] } };
最优实现方案
方案1:原生遍历合并(直观易读)
通过遍历第二个对象的日期键,将消息数组合并到第一个对象的对应日期中,同时避免修改原对象:
const mergeChatMessages = (dataA, dataB) => { // 复制初始消息结构,不修改原数据 const merged = { ...dataA.messages }; // 遍历第二个数据的所有日期分组 for (const date in dataB.messages) { if (merged[date]) { // 已有该日期,合并两个数组 merged[date] = [...merged[date], ...dataB.messages[date]]; } else { // 无该日期,直接添加分组 merged[date] = [...dataB.messages[date]]; } } return { messages: merged }; }; // 使用方法 const result = mergeChatMessages(data1, data2);
方案2:函数式写法(简洁优雅)
利用Set收集所有唯一日期,再通过reduce合并对应数组:
const mergeChatMessages = (dataA, dataB) => { // 获取所有不重复的日期键 const allDates = new Set([ ...Object.keys(dataA.messages), ...Object.keys(dataB.messages) ]); // 合并每个日期下的消息数组 const mergedMessages = [...allDates].reduce((acc, date) => { acc[date] = [ ...(dataA.messages[date] || []), ...(dataB.messages[date] || []) ]; return acc; }, {}); return { messages: mergedMessages }; }; // 使用方法 const result = mergeChatMessages(data1, data2);
可选:消息去重
如果存在重复id的消息,可通过Map实现去重(保留最后出现的消息):
const mergeChatMessages = (dataA, dataB) => { const allDates = new Set([ ...Object.keys(dataA.messages), ...Object.keys(dataB.messages) ]); const mergedMessages = [...allDates].reduce((acc, date) => { // 用id作为键去重,后续消息覆盖之前的 const messageMap = new Map(); (dataA.messages[date] || []).forEach(msg => messageMap.set(msg.id, msg)); (dataB.messages[date] || []).forEach(msg => messageMap.set(msg.id, msg)); acc[date] = Array.from(messageMap.values()); return acc; }, {}); return { messages: mergedMessages }; };
以上方案均为原生JavaScript实现,无需依赖第三方库,时间复杂度为O(n)(n为所有消息总数),性能高效且易维护。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

