查找映射到 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
循环更有效,原因有二:
它发生在引擎的代码中,让引擎优化
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.keys
与 filter
:
一起使用
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
我正在 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
循环更有效,原因有二:它发生在引擎的代码中,让引擎优化
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.keys
与filter
: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