JavaScript使用forEach循环对对象数组按值分组去重的实现问题
JavaScript对象数组按值去重调整方案
问题原因
你当前的代码无法去重的核心问题有两个:
- 你在
forEach循环内部每次仅将单条当前数据存入elements数组,每次生成的Set仅包含单个元素,无法跨循环判断重复 - 没有全局的容器存储已经出现过的对象标识,无法识别之前已经处理过的重复值
调整后实现代码
你可以用一个Set存储已出现对象的唯一标识,可选两种判断方式:如果需要全字段匹配就序列化整个对象,如果仅需按userid+articleid组合去重就用组合字符串,性能更高。
var newMessage = ''; function realTime(){ db.collection('chat').where('userid', '==', <?php echo $id; ?>) .orderBy('time') .onSnapshot(function(snapshot) { newMessage = ''; const existedSet = new Set(); // 每次快照更新重置去重集合 const uniqueData = []; // 存储去重后的结果 snapshot.docChanges().forEach(function(change) { if (change.type === "added") { const currentData = change.doc.data(); // 方式1:全字段匹配去重 const dataFlag = JSON.stringify(currentData); // 方式2:仅按userid+articleid组合去重,性能更高 // const dataFlag = `${currentData.userid}-${currentData.articleid}`; if (!existedSet.has(dataFlag)) { existedSet.add(dataFlag); uniqueData.push(currentData); // 这里补充你生成newMessage的逻辑,原代码中这部分缺失 // 示例:newMessage += 你拼接的聊天消息HTML字符串 } } }); console.log(uniqueData); // 就是去重后的结果 if (chatHTML != newMessage) { $('.msg_body').append(newMessage); } }); }
效果验证
针对你给出的示例数组,逻辑验证如下:
const arr = [ { userid: "5", articleid: "3"}, { userid: "5", articleid: "3"}, { userid: "5", articleid: "3"}, { userid: "1", articleid: "2"} ]; const existedSet = new Set(); const res = []; arr.forEach(item => { const flag = `${item.userid}-${item.articleid}`; if(!existedSet.has(flag)){ existedSet.add(flag); res.push(item); } }) console.log(res); // 输出:[{userid: "5", articleid: "3"},{userid: "1", articleid: "2"}] 完全符合预期
内容的提问来源于stack exchange,提问作者Medhat Farid
相关产品推荐
相关产品推荐

