【问题标题】:Improving performance while iterating two nested loops [closed]在迭代两个嵌套循环时提高性能[关闭]
【发布时间】:2015-03-05 21:08:44
【问题描述】:

我计算出生地的“Top-5-List”,以这种形式组织在一个对象数组中

var myObjArr =[
{
  "birth": 
  {
    "year": 2012,
    "name": "Manchester, Vermont, USA",
  }
} , (and so on)
];

然而,我的方法似乎不太高效:

for (var i = 0; i < myObjArr.length; i++) {

    var alreadyListed = -1;

    for (var j = 0; j < resultData.length; j++) {
      if(resultData[j].key == myObjArr[i]['birth']['name']) { // birthname already in resultData   
        alreadyListed = j;
        break;
      }
    }
    if(alreadyListed != -1 ) { // birthname already in resultData -> raise count
      resultData[alreadyListed].count += 1;

    }else {  // birthname not yet in resultData -> add to resultData
      resultData.push({key: myObjArr[i]['birth']['name'], count: 1 });    
    }
  }
}  

Neiter javascript 的 forEach 和 angulars angular.forEach 似乎提高了性能。有什么建议吗?

【问题讨论】:

  • 这个网站不是要求改进工作代码的地方。你应该试试codereview.stackexchange.com
  • 您遇到的问题是算法问题。切换到另一种迭代机制不会有任何帮助。

标签: javascript arrays performance loops


【解决方案1】:

您可以将对象用作字典,而不是使用数组并通过迭代查找键,这样第二个“循环”由 Javascript 实现在查找对象键时完成(也可能不是线性扫描但哈希表查找):

var result = {};
myObjArr.forEach(function(obj) {
    var key = "!" + obj.birth.name;
    result[key] = 1 + (result[key] || 0);
});

在将对象用作字典时,我总是在键前添加 "!",因为所有 Javascript 对象都具有继承的 constructor 属性,我不想干扰它。

(x || 0) 的技巧是当一个名字以前没有见过时以 0 开头(undefined 在 Javascript 中是错误的)。将 1 加到 undefined 会导致 NaN

如果你真的需要一个数组,那么代码只是稍微复杂一点:

var result = [];
var index = {};
myObjArr.forEach(function(obj) {
    var key = "!" + obj.birth.name;
    var ix = index[key];
    if (ix === undefined) {
        // Allocate a new entry
        index[key] = result.length;
        result.push({key:key, count:1});
    } else {
        result[ix].count += 1;
    }
});

【讨论】:

  • 太好了!有没有办法将它直接写入对象数组(使“结果”成为数组)?
  • @user3351652:查看编辑以获取在数组中生成结果的版本。
猜你喜欢
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 2021-07-04
  • 1970-01-01
  • 2012-11-25
相关资源
最近更新 更多