【问题标题】:Convert Array of objects to Hash with a field as the key以字段为键将对象数组转换为哈希
【发布时间】:2013-03-23 13:57:48
【问题描述】:

我有一个对象数组:

[
  #<User id: 1, name: "Kostas">,
  #<User id: 2, name: "Moufa">,
  ...
]

我想将其转换为以 id 作为键和对象作为值的哈希。现在我就是这样做的,但我知道有更好的方法:

users = User.all.reduce({}) do |hash, user|
  hash[user.id] = user
  hash
end

预期输出:

{
  1 => #<User id: 1, name: "Kostas">,
  2 => #<User id: 2, name: "Moufa">,
  ...
}

【问题讨论】:

  • @SergioTulentsev,我在看Enumerable#group_by,这几乎就是我要找的。我只是认为它有一个版本,而不是为值构建数组,它更具侵略性并且只保留一个值。

标签: ruby type-conversion


【解决方案1】:
users_by_id = User.all.map { |user| [user.id, user] }.to_h

如果你使用 Rails,ActiveSupport 提供Enumerable#index_by

users_by_id = User.all.index_by(&:id)

【讨论】:

  • 我个人更喜欢mash 方式而不是Hash[...] 方式。它读起来更干净,更像红宝石。
  • 我相信你的 Ruby >= 2.1 需要稍微修正,你想要 .to_h 而不是 .to_a 例如users = User.all.map { |u| [u.id, u] }.to_h
【解决方案2】:

使用each_with_object 而不是reduce,您将获得更好的代码。

users = User.all.each_with_object({}) do |user, hash|
  hash[user.id] = user
end

【讨论】:

  • 我们又要走inject/each_with_object/Hash/mash 路径了吗? :-) bugs.ruby-lang.org/issues/show/666
  • @tokland:是的,当我看到你的评论时,这是我脑海中的第一个想法 :)
猜你喜欢
  • 2011-02-23
  • 1970-01-01
  • 2015-01-04
  • 2019-10-27
  • 2019-05-23
  • 2012-10-29
  • 2016-02-05
  • 2011-06-29
  • 1970-01-01
相关资源
最近更新 更多