JavaScript键未知的嵌套对象如何检查值是否存在并去重
你之前用some、indexOf写的逻辑没生效,本质原因是:当前数组里存的是键值对对象,不是用户名字符串本身,直接拿字符串和对象做匹配,自然永远命中不了。
基于你现在的现有数据结构,完全不需要嵌套循环+计数器的笨重写法,核心存在性判断可以压缩到一行实现:
现有结构下的简洁实现
直接用Array.some方法完成存在性检查,替换掉原来的双层循环逻辑:
if(users[data.roomname]){ const currentRoomUsers = users[data.roomname]; // 存在性判断核心逻辑 const isDuplicate = currentRoomUsers.some( userEntry => Object.values(userEntry)[0] === data.username ); // 仅非重复用户才推入数组 if(!isDuplicate) { currentRoomUsers.push(user); } }
逻辑说明
Array.some的特性是遍历数组时,只要找到第一个满足条件的元素就立刻返回true,不会执行无意义的全量遍历,性能比自己写计数器循环更好- 因为每个用户条目都是只包含一个socket.id为键、用户名为值的单键对象,用
Object.values(userEntry)[0]可以直接取出存储的用户名做匹配,不需要额外遍历对象的键列表
更高效的结构优化建议
你当前的存储结构存在冗余,查重操作需要遍历整个用户数组,时间复杂度为O(n),当房间内用户数量较多时性能会明显下降。
可以将单房间下的存储结构调整为以用户名为键、对应socket.id为值的对象,查重不需要遍历,直接通过键查询即可,时间复杂度为O(1):
// 优化后的最终结构示例 users = { RoomABC: { "Mr Chipps": "YidwzgUHPHEGkQIPAAAD", "Mr T": "JG-gtBMyPm0C1Hi1AAAF" } } // 对应简化后的写入逻辑 if(users[data.roomname]){ // 直接通过键判断用户名是否存在,无需遍历 if(!users[data.roomname][data.username]) { users[data.roomname][data.username] = socket.id; } } else { users[data.roomname] = { [data.username]: socket.id }; }
内容的提问来源于stack exchange,提问作者TenG
相关产品推荐
相关产品推荐

