散列中的增量值

时间:2010-08-05 00:23:10

标签: ruby hash

我有一堆帖子里面有类别标签。 我试图找出每个类别被使用了多少次。

我正在使用带有mongodb的rails,但我不认为我需要从db中获取类别的出现,因此mongo部分无关紧要。

这是我到目前为止所拥有的

@recent_posts = current_user.recent_posts #returns the 10 most recent posts
@categories_hash = {'tech' => 0, 'world' => 0, 'entertainment' => 0, 'sports' => 0}
    @recent_posts do |cat|
       cat.categories.each do |addCat|
         @categories_hash.increment(addCat) #obviously this is where I'm having problems
       end
     end
end

帖子的结构是

{"_id" : ObjectId("idnumber"), "created_at" : "Tue Aug 03...", "categories" :["world", "sports"], "message" : "the text of the post", "poster_id" : ObjectId("idOfUserPoster"), "voters" : []}

我愿意接受关于如何获得类别数量的建议,但我想最终获得选民的数量,所以在我看来,最好的方法是增加categories_hash,然后添加选民.length,但一次只有一件事,我只想弄清楚如何增加哈希值。

2 个答案:

答案 0 :(得分:8)

如果您不熟悉map / reduce并且不关心扩展,那么这不像map / reduce那么优雅,但对于小型网站来说应该足够了:

@categories_hash = Hash.new(0)
current_user.recent_posts.each do |post|
  post.categories.each do |category|
    @categories_hash[category] += 1
  end
end

答案 1 :(得分:1)

如果你正在使用mongodb,那么使用map / reduce操作聚合标签的优雅方法就是。 Mongodb使用JavaScript代码支持map / reduce操作。 Map / reduce在数据库服务器上运行,即您的应用程序不必检索和分析每个文档(对于大型集合而言,这不能很好地扩展)。

作为一个例子,这里是我在博客文章集合中使用的map和reduce函数,用于聚合标记的用法(用于在侧边栏中构建标记云)。文章集合中的文档有一个名为“tags”的键,它包含一个字符串数组(标记)

map函数只对每个使用过的标记发出1来计算它:

function () {
  if (this.tags) {
    this.tags.forEach(function (tag) {
      emit(tag, 1);
    });
  }
}

reduce函数总结了计数:

function (key, values) {
  var total = 0;
  values.forEach(function (v) {
    total += v;
  });
  return total;
}

因此,数据库返回一个散列,该散列具有每个标记的键及其使用计数值。 E.g:

{ 'rails' => 5, 'ruby' => 12, 'linux' => 3 }