所以我试图用下划线来考虑更好的方法:
state.attributes = _.reduce(list, function(memo, item){
memo['neighborhood'] = (memo['neighborhood'] || []);
var isNew = true;
_.each(memo['neighborhood'], function(hood){
if (hood.name === item.data.neighborhood) {
hood.count++; isNew=false;
}
});
if(isNew){
memo['neighborhood'].push({name:item.data.neighborhood, count:1});
}
return memo;
});
我想将列表的各种名称组合成一个唯一名称列表,其中包含每个唯一名称出现次数的计数。看起来正是下划线设计要解决的那种问题,但我能想到的最佳解决方案似乎并不优雅。
答案 0 :(得分:5)
我不是一个underscore.js用户,但我猜_.groupBy()
适合这种情况:
var attributes = _.groupBy(list, function (item) {
return item.data.neighborhood
})
它不会以您想要的方式返回数组,但它包含您需要的所有信息。因此,您在attributes["foo"]
中的所有项目中都有“foo”作为neighborhood
值属性,因此在attributes["foo"].length
中包含了{{1}}的计数。
答案 1 :(得分:1)
也许有更好的underscore.js方式,但您已经可以应用其他优化:
使用name: count
地图,而不是使用数组来跟踪名称和计数。这可以通过对象轻松完成:
state.attributes = _.reduce(list, function(memo, item){
var n = item.data.neighborhood;
memo['neighborhood'] = (memo['neighborhood'] || {});
memo['neighborhood'][n] = memo['neighborhood'][n] + 1 || 1;
return memo;
});
这样做有效,因为如果列表中尚未显示item.data.neighborhood
,memo['neighborhood'][item.data.neighborhood]
将返回undefined
而undefined + 1
会返回NaN
。
由于NaN
评估为false
,因此表达式NaN || 1
将导致1
。