我正在我的应用程序中创建一个类似Reddit的投票系统。每个对象(线程)都有一个score属性和一个类似于父对象的对象数组(将其视为对线程的注释)。
这是一个简化的例子:
{
id: '123fdx12c1',
author: 'Anon',
score: 1,
users: [
{
id: '321fdx12c1',
name: 'anon',
score: 1
},
{
id: 'asd123f1fd1',
name: 'anon',
score: 1
}
]
}
现在想象一下像这样的大量对象。每当用户投票时,将调度具有正确id的动作以查找匹配的id并更改分数值 我的方法:
case 'VOTE':
return state.map((question) => {
question.users = question.users.map((user) => {
if (user.id == action.id) {
return {
...user,
voteStatus: action.voteStatus,
score: action.score
}
}
return user;
});
if (question.id == action.id) {
return {
...question,
voteStatus: action.voteStatus,
score: action.score
}
}
return question;
});
它映射整个数组只是为了改变一个对象的一个属性。有没有更快的方法呢?
答案 0 :(得分:1)
最快的是id查找,因此即使对于很多ID,按id查找项目的时间也几乎相同:
{
'123fdx12c1' : {
author: 'Anon',
score: 1,
users: [ '321fdx12c1', 'asd123f1fd1' ]
},
'321fdx12c1' : {
name: 'anon',
score: 1
},
'asd123f1fd1' : {
name: 'anon',
score: 1
}
}
作为旁注,通常,解释语言中的函数调用比本机代码慢
在某些浏览器中,.map
可能比循环慢约10-100倍。
答案 1 :(得分:0)
我知道.map
和.filter
因各种(主要是好的)原因而受欢迎。但有时候老式的for循环是值得使用的,因为它们是基本语言,除了你自己添加的东西之外,它们没有额外的开销:
case 'VOTE':
var updated = false;
for (var i = 0; i < state.length; i++) {
if (state[i].id === action.id) {
state[i].score += action.score; // or whatever
break;
}
for (var j = 0; j < state[i].users.length; j++) {
if (state[i].users[j].id === action.id) {
state[i].users[j].score += action.score; // or whatever
updated = true;
break;
}
}
if (updated) { break; }
}
请注意,我们会在找到匹配项时停止搜索,而无需复制到新数组。
搜索整个数组可能感觉操作繁重,但不要搞错,.map
也是在幕后做这件事。
答案 2 :(得分:0)
从问题数组中获取问题:
const question = state.find(question => (question.id === action.id));
// do something with question
然后找到该用户并更新其分数:
const user = question && question.users.find(user => (user.id === action.id));
// do something with user