一种使用javascript聚合和分组活动供稿的项目的方法

时间:2012-06-07 11:45:54

标签: javascript grouping aggregate-functions underscore.js aggregation

我有一个活动流项目列表,我希望将类似的项目组合在一起。例如,而不是有4个条目说“乔喜欢你的快乐帖子”,“莎拉喜欢你的快乐帖子”,“鲍勃喜欢你的快乐帖子”,“汤姆喜欢你的快乐帖子”,应该有一个说“乔,Sarah和另外2人喜欢你的快乐帖子“。当项目聚合时,聚合帖子将使用其部分的最新时间戳。

活动流不是无穷无尽的,只包含过去一周的项目,因此所有与名词(noun.activityType + noun.id)和动词的属性匹配的项目应该组合在一起。每个活动项目都有一个演员(谁做过),目标(发布者是谁的动词),动词(演员做了什么)和名词(动词作用于什么对象)。

我把这个测试数据集放在jsfiddle上供你们玩:

http://jsfiddle.net/yu2P8/1/

{
        "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
        }
}

一种策略是在创建活动项时聚合服务器端,但我想在客户端使用诸如下划线之类的库来探索是否可行。

1 个答案:

答案 0 :(得分:3)

所以我使用下划线组和地图来解决这个问题。我首先使用名词和动词作为关键字来使用下划线组。然后我使用下划线缩减功能将结果合并到一个条目中。

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