1

所以我正在尝试用下划线想一个更好的方法来做到这一点:

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;
});

我想将列表的各种名称组合成一个唯一名称列表,并计算每个唯一名称出现的次数。下划线似乎正是为了解决这种问题而设计的,但我能想到的最佳解决方案似乎不够优雅。

4

2 回答 2

5

我不是 underscore.js 用户,但我想_.groupBy()适合这种情况:

var attributes = _.groupBy(list, function (item) {
    return item.data.neighborhood
})

它不会以您想要的确切方式返回数组,但它包含您需要的所有信息。因此,您拥有attributes["foo"]所有具有“foo”作为neighborhood值属性的项目,因此在attributes["foo"].length它们的计数中。

于 2012-05-06T09:25:25.197 回答
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]将返回undefinedundefined + 1返回NaN
由于NaN计算结果为false,表达式NaN || 1将导致1

于 2012-05-06T08:26:11.710 回答