Ruby:将数组映射到hash,在哈希中创建一个数组

时间:2016-07-14 20:55:51

标签: arrays ruby hash

我正在创建一个简单的分析图表并避免实时重度查询我需要将缓存的结果数据集保存在专用于这些统计信息的表中。

任何用户尝试一些课程,我想使用状态保存课程的ID。像

这样的东西
{ "invited": [1,3,6], "done": [2,9] }

我写这个函数

u.courses.map { |w| [w.status, []<<w.id]  }.to_h

但当然每次迭代我的数组都已初始化,所以我有

{"invited"=>[5101]}

如果我尝试

u.courses.map { |w| [w.status, []<<w.id]  }

我获得了

[["invited", [1]], ["invited", [748]], ["invited", [1445]], ["invited", [2113]], ["invited", [2833]], ["invited", [6017]], ["invited", [4146]], ["invited", [5101]]]

如何在第一次迭代中创建数组,将其保留在我的地图中?

2 个答案:

答案 0 :(得分:2)

您可以尝试each_with_object

u.courses.each_with_object({}){|w, o| (o[w.status] ||= []) << w.id}

reduce/inject

u.courses.reduce({}){|o, w| (o[w.status] ||= []) << w.id}

答案 1 :(得分:0)

u.course.each_with_object({}) { |course, h|
  h.update(course.status=>[course.id]) { |_,o,n| o+n } }

这使用Hash#update(aka merge!)的形式,它使用块({ |_,o,n| o+n })来确定合并的两个哈希中存在的键的值。第一个块变量是公共密钥。由于在块计算中没有使用它,我用下划线表示它,这是常见的做法。有关其他两个块变量的说明,请参阅update的文档。