我计算了以这种形式在一系列对象中组织的出生地的“前5名单”
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
似乎可以改善效果。有什么建议吗?
答案 0 :(得分:1)
您可以将对象用作字典而不是使用数组并通过迭代查找键,这样第二个“循环”由Javascript实现在查找对象键时完成(也可能不是线性扫描但哈希表查找):
var result = {};
myObjArr.forEach(function(obj) {
var key = "!" + obj.birth.name;
result[key] = 1 + (result[key] || 0);
});
当使用对象作为词典时,我总是在键前面添加"!"
,因为所有Javascript对象都有一个继承的constructor
属性,我不想干扰它。 / p>
(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;
}
});