编写JavaScript函数:设置消息数组中各用户最后一条消息isSeen为true
解决:每个用户仅最后一条消息标记为已读(isSeen: true)
需求明确
给定包含用户标识(如userId)和isSeen属性的消息数组,处理后需满足:每个用户的所有消息中,仅最后一条(数组中最后出现的该用户消息)的isSeen为true,其余同用户消息的isSeen设为false。
解决方案代码
function markLastMessageAsSeen(messages) { // 记录每个用户最后一条消息的索引 const userLastIndexMap = {}; // 第一次遍历:锁定每个用户最后一条消息的位置 messages.forEach((message, index) => { userLastIndexMap[message.userId] = index; }); // 第二次遍历:批量设置isSeen属性 return messages.map((message, currentIndex) => ({ ...message, // 浅拷贝原对象,避免污染原始数据 isSeen: currentIndex === userLastIndexMap[message.userId] })); }
代码说明
- 记录最后索引:通过一次遍历,用对象存储每个
userId对应的最后一条消息在数组中的索引,确保后续能快速定位目标消息。 - 批量设置状态:二次遍历数组时,对比当前消息的索引与该用户的最后消息索引,匹配则设为已读(
true),否则设为未读(false)。 - 数据隔离:使用对象展开运算符
...message浅拷贝原消息对象,避免直接修改原始数组数据。如果消息存在嵌套属性,可替换为深拷贝(如JSON.parse(JSON.stringify(message)))。
示例验证
输入原始消息数组:
const rawMessages = [ { userId: 1, content: "Hi there", isSeen: true }, { userId: 2, content: "Hello!", isSeen: false }, { userId: 1, content: "Need help?", isSeen: false }, { userId: 2, content: "Any updates?", isSeen: true }, { userId: 3, content: "New notification", isSeen: false } ];
调用函数处理后输出:
[ { userId: 1, content: "Hi there", isSeen: false }, { userId: 2, content: "Hello!", isSeen: false }, { userId: 1, content: "Need help?", isSeen: true }, { userId: 2, content: "Any updates?", isSeen: true }, { userId: 3, content: "New notification", isSeen: true } ]
常见bug规避
- 避免单遍历实时修改:不要在一次遍历中遇到同用户就标记之前的消息为
false,这种逻辑会在用户消息不连续时遗漏早期消息的状态修改。 - 不要破坏原数组顺序:不要通过反转数组处理后再反转回来,这种操作会打乱原始消息的时间/展示顺序,除非数组本身是倒序排列。
- 注意数据引用:直接修改原数组的消息对象会污染原始数据,必须通过拷贝生成新对象。
内容的提问来源于stack exchange,提问作者Ramy Hadid
相关产品推荐
相关产品推荐

