Mon*_*key 5 javascript grouping aggregate-functions aggregation underscore.js
我有一个活动流项目列表,我希望将类似的项目组合在一起。例如,除了要有4个条目说“乔喜欢您的快乐帖子”,“莎拉喜欢您的快乐帖子”,“鲍勃喜欢您的快乐帖子”,“汤姆喜欢您的快乐帖子”之外,应该有一个标题为“乔”的条目,莎拉(Sarah)和另外2个人喜欢您的快乐帖子”。汇总项目时,汇总的帖子将使用其各个部分的最新时间戳。
活动流不是无止境的,仅包含上周的项目,因此应将所有与名词(noun.activityType + noun.id)和动词的属性匹配的项目组合在一起。每个活动项都有一个演员(执行者),目标(将其提要发布到谁的提要上),动词(演员执行了什么操作)和名词(作用在什么对象上的动词)。
我已将此测试数据集放在jsfiddle上,以供你们使用:
{
"pts": 0,
"verb": "follow",
"target": "mike",
"actor": "test01",
"title": "test01 has started following you",
"published": "2012-06-04T22:34:01.914Z",
"_id": "4fcd37d9c7f1f40100000d7d",
"noun": {
"id": "mike",
"activityType": "profile",
"title": null
}
}
Run Code Online (Sandbox Code Playgroud)
一种策略是在创建活动项目时聚合服务器端,但是我想探索一下使用下划线之类的库在客户端执行此操作,以查看它是否可行。
所以我使用下划线组和地图解决了这个问题。我首先使用名词和动词作为键来使用下划线组。然后我使用下划线归约函数将结果合并为一个条目。
var groupedResults = _.groupBy(data, function(val){
return val.noun.id + val.noun.activityType + val.verb;
});
function reducer(activities, key) {
var reduction = _.reduce(activities, function(a, b){
if (a && a.actors && !_.include(a.actors, b.actor))
a.actors.push(b.actor);
else
a.actors = [b.actor];
a.published = a.published < b.published ? b.published : a.published;
return a;
}, activities[0]);
reduction.pronoun = getActorsSummaryString(reduction);
reduction.title = summarizeTitle(reduction);
return reduction;
}
finalResults = sortByRecent(_.map(groupedResults, reducer));
Run Code Online (Sandbox Code Playgroud)