查找映射到 javascript 中的值的所有键。和有效的替代品

finding all keys that map to a value in javascript. And efficient alternatives

我正在 javascript 开发一个应用程序,每个用户都在一个房间里。没有两个用户共享相同的名称,也没有两个房间共享相同的名称。目前我是这样设置的:

var userroommap = {
  username: "room",
  username2: "room",
  username3: "room2"
}

获取用户所在的房间就像

一样简单
userroommap["user"]

但为了获得房间中的所有用户,我必须像这样遍历整个用户空间图:

for (var x in userroommap) {
  if (userroommap[x] == "room")
    //user x is present in room 
  }
}

在我的应用程序中,我必须经常知道哪些用户在哪些房间中,因此我正在考虑使用另一个对象将所有用户保存在一个房间中,例如:

var roomusermap = {
  room:["username", "username2"],
  room2:["username3"]
}

将用户添加到房间是微不足道的,因为您所要做的就是附加到数组,但是从房间中删除用户名需要遍历数组并成为一个不错的操作。这已经是我的问题的一个不错的解决方案,但我很好奇是否有更好的解决方案。那么:有没有更好的方法来 (i) 存储 roomusermap,也许没有数组?或者,或者 (ii) 查找房间中的所有用户?

除非您确定了真实的、真实的性能问题,否则我会坚持使用简单的解决方案。

话虽如此,但有几点想告诉你:

  • 所有现代 JavaScript 引擎都为您提供 Object.keys 函数,其中 returns 一个对象的 自己的可枚举数组 特性。这可能比 for-in 循环更有效,原因有二:

    1. 它发生在引擎的代码中,让引擎优化

    2. for-in 在原型对象中寻找可枚举的属性,而 Object.keys 知道它只应该在那个特定的对象中寻找

  • 您的 roomusermap 可以包含每个房间的地图,不需要使用数组。

    var roomusermap = {
        room: {
            username: user,
            username2: user2
        },
        room2: {
            username3: user3
        }
    };
    

    将用户添加到房间变为:

    userroommap[username] = roomname;
    roomusermap[roomname][username] = user;
    

    删除用户是:

    delete userroommap[username];
    delete roomusermap[roomname][username];
    
  • 如果您发现这些地图对象存在性能问题,请记住,从对象 (delete) 中删除 属性 会将对象放入"dictionary mode" 在几个 JavaScript 引擎上(以前处于更优化的状态),显着影响查找该对象属性所需的时间。

    因此,在 属性 查找性能开始成为问题的非常假设的情况下,您可以考虑存储 undefined 而不是删除 属性。例如,而不是:

    delete userroommap[username];
    delete roomusermap[roomname][username];
    

    你会的

    userroommap[username] = undefined;
    roomusermap[roomname][username] = undefined;
    

    但是,您必须调整对用户是否在房间内的检查,并且您不能再使用 Object.keys(单独)获取列表,因为您必须除草输出值为 undefined 的属性。您可以将 Object.keysfilter:

    一起使用
    var map = roomusermap[roomname];
    var users = Object.keys(map).filter(function(username) {
        return map[username] !== undefined;
    });
    

    所以只有当您发现 真正的问题 由对象进入字典模式引起时,您才会 真的 想要这样做.

上一个答案中描述的数据结构称为 BiMap

BiMap 理想地为 value: keys 查找操作提供与 key: values 查找相同的性能。它通常通过在内部管理两个单独的映射(一个具有 forward-mapping {key:values} 和一个具有 reverse-mapping {value:keys}).

如果您不自己动手,可以使用现有的实现。 https://www.npmjs.com/package/bimap