如何基于对象值从两个数组生成含用户最新交互的对象数组
合并消息数组获取与每个用户的最新交互记录
高效解决方案
核心思路是利用对象/Map的O(1)键查找特性,一次遍历就能完成每个用户最新记录的维护,时间复杂度为O(n),比循环对比+排序的方案更高效:
interface MsgSlice { messageId: string; messageDataSlice: { senderId?: string; receiverId: string; timestamp: number; }; }; const latestReceivedMsgs: MsgSlice[] = [ { messageId: "messageId1", messageDataSlice: { senderId: "userId1", receiverId: "ownerId", timestamp: 101, }, }, { messageId: "messageId3", messageDataSlice: { senderId: "userId2", receiverId: "ownerId", timestamp: 103, }, }, { messageId: "messageId5", messageDataSlice: { senderId: "userId3", receiverId: "ownerId", timestamp: 105, }, }, ]; const latestSentMsgs: MsgSlice[] = [ { messageId: "messageId2", messageDataSlice: { receiverId: "userId1", timestamp: 102, }, }, { messageId: "messageId4", messageDataSlice: { receiverId: "userId3", timestamp: 104, }, }, ]; // 1. 统一所有交互的格式 const allInteractions = [ // 收到的消息:交互用户是senderId ...latestReceivedMsgs.map(msg => ({ user: msg.messageDataSlice.senderId!, messageId: msg.messageId, timestamp: msg.messageDataSlice.timestamp })), // 发送的消息:交互用户是receiverId ...latestSentMsgs.map(msg => ({ user: msg.messageDataSlice.receiverId, messageId: msg.messageId, timestamp: msg.messageDataSlice.timestamp })) ]; // 2. 维护每个用户的最新交互记录 const userLatestMap: Record<string, {messageId: string, timestamp: number}> = {}; allInteractions.forEach(interaction => { const current = userLatestMap[interaction.user]; // 无记录或当前时间戳更大时更新 if (!current || interaction.timestamp > current.timestamp) { userLatestMap[interaction.user] = { messageId: interaction.messageId, timestamp: interaction.timestamp }; } }); // 3. 转换为目标数组格式 const latestInteraction = Object.entries(userLatestMap).map(([user, data]) => ({ user, messageId: data.messageId, timestamp: data.timestamp })); console.log(latestInteraction);
步骤拆解
- 统一格式:将收到/发送的消息转换为包含
user(交互对象ID)、messageId、timestamp的标准结构,消除来源差异。 - 维护最新记录:通过对象的键快速定位用户,仅保留时间戳最大的交互——避免了重复排序和过滤,大幅提升效率。
- 转换结果:将对象的键值对映射为期望的数组结构,直接得到最终结果。
注意事项
- 如果实际场景中
latestReceivedMsgs的senderId可能为undefined,可以在map时添加过滤:msg.messageDataSlice.senderId && {...},避免无效条目干扰。 - 若需要保持用户顺序,可以用
Map替代普通对象(Map会保留插入顺序),遍历方式调整为Array.from(userLatestMap.entries())即可。
内容的提问来源于stack exchange,提问作者tenxsoydev
相关产品推荐
相关产品推荐

