在大型对象中改变单个对象属性的最快方法是什么?

时间:2017-09-17 20:26:18

标签: javascript reactjs optimization redux react-redux

我正在我的应用程序中创建一个类似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;
  });

它映射整个数组只是为了改变一个对象的一个​​属性。有没有更快的方法呢?

3 个答案:

答案 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