Javascript 搜索数百万条记录的最快方法是两个js对象的组合
我有数以百万计的信息对象Javascript 搜索数百万条记录的最快方法是两个js对象的组合,javascript,ecmascript-6,time-complexity,javascript-objects,Javascript,Ecmascript 6,Time Complexity,Javascript Objects,我有数以百万计的信息对象 messages: [ { id: Int, text: String, userId: Int, receiverId: Int, }, 和成千上万的用户 users: [ { id: Int, name: String, }, 我需要处理两个对象并返回一个格式的对象 [{ message, userFromName, userToName }] 我读过一
messages: [
{
id: Int,
text: String,
userId: Int,
receiverId: Int,
},
和成千上万的用户
users: [
{
id: Int,
name: String,
},
我需要处理两个对象并返回一个格式的对象
[{ message, userFromName, userToName }]
我读过一些关于数组方法的文章,比如find、filter,其中一些和所有的都比原生for和foreach慢
我还编写了一个函数,其中包含两个foreach循环
msgData.forEach(function(msg,i) {
...iterating every msg
userData.forEach(function(user) {
...iterating every user id over message sender and receiver id
});
});
O(n)平方码的复杂性
如何在较短的时间内获得所需的格式?将
用户
转换为字典,以实现快速、非迭代的查找:
本机对象:
let userDict = users.reduce((o,u)=> {
o[u.id]=u.name;
return o;
}, {});
地图:
这是O(n)。使用此词典,您可以将msgData forEach简化为:
let result = msgData.map(msg => {
return { message: msg.text, userFromName: userDict[msg.userId], userToName: userDict[msg.receiverId]};
});
这也是O(n),因为对象和贴图查找都是O(1)。有关这些方面的性能详细信息,请参阅。与当前的O(n^2)解决方案相比,无论采用哪种方法,性能都会有显著提高。假设两个数组之间有一个共同的键,您可以使用哈希映射数据结构,在Javascript中可以表示为简单的普通对象,例如:
constusers=[{id:1,名称:'Marcela'},{id:2,名称:'Ana'}];
const messages=[{id:1,message:'她是一位伟大的平面设计师'},{id:2,message:'她喜欢看电影'}];
//#1将一个数组转换为哈希映射
const userHashMap={};
//O(N)
for(让用户对用户){
userHashMap[user.id]=用户;
}
//上面的代码将存储一个类似DS的
// {
// 1:
// {
//id:1,
//姓名:“玛塞拉”
// },
// 2:
// {
//id:2,
//姓名:“安娜”
// }
// }
//#2现在您可以在O(N)中迭代消息
//我们可以得到用户的价值
//在常量时间O(1)中(这是HashMaps最重要的用法):
messages.forEach(message=>{
log(`This id message${message.id}属于${userHashMap[message.id].name}`);
log(`Message for${userHashMap[Message.id].name}:${Message.Message}`);
});
如果让服务器处理这些数据,可能效率会更高。如果可以将数据转换为id为键的对象,如messages={“id1”:{…},“id2”:{…}
和users={“id1”:{…},“id2”:{…}
然后您就可以大大提高性能,因为现在查找是通过对象键完成的,而不是通过数组进行迭代。“我需要处理两个对象”-哪一个?“并以格式返回一个对象”-你的意思是返回一个包含多个对象的数组吗?是什么让你认为find
或some
比forEach
慢?将它们放在一些Map
s中:发送方键入的消息,接收方键入的消息,由id键入的用户。这应该允许您足够高效地执行大多数搜索。
let result = msgData.map(msg => {
return { message: msg.text, userFromName: userDict[msg.userId], userToName: userDict[msg.receiverId]};
});