Ruby:从哈希数组生成哈希

Ruby:从哈希数组生成哈希,ruby,arrays,hash,Ruby,Arrays,Hash,我有以下几点 friends = [{ name: "Jack", attr1:"def", attr2:"def" }, { name: "Jill", attr1:"def", attr2:"def" }] 我想把上面的表示转换成如下的散列 friends = { "Jack" => { attr1: "def", attr2:"def" }, "Jill" => { attr1: "def", attr2: "def" } } 在Ruby中有什么优雅的方法可以做到这一点吗?

我有以下几点

friends = [{ name: "Jack", attr1:"def", attr2:"def" }, { name: "Jill", attr1:"def", attr2:"def" }]
我想把上面的表示转换成如下的散列

friends = { "Jack" => { attr1: "def", attr2:"def" }, "Jill" => { attr1: "def", attr2: "def" } }

在Ruby中有什么优雅的方法可以做到这一点吗?

当您想将一个数组转换成另一个数组时,请使用
collect

Hash[friends.map { |f| _f = f.dup; [_f.delete(:name), _f] }]
# => {"Jack"=>{:attr1=>"def", :attr2=>"def"}, "Jill"=>{:attr1=>"def", :attr2=>"def"}}
friends = Hash[
  friends.collect do |f|
    _f = f.dup
    name = _f.delete(:name)
    [ name, _f ]
  end
]

您可以使用
hash[]
轻松创建新的哈希,并为其提供一个包含一系列键/值对的数组。在这种情况下,
name
字段将从每个数组中删除。

当您要将一个数组转换为另一个数组时,请使用
collect

friends = Hash[
  friends.collect do |f|
    _f = f.dup
    name = _f.delete(:name)
    [ name, _f ]
  end
]
friends.each_with_object({}) do |f, o|
    f = f.dup
    o[f.delete :name] = f
end
您可以使用
hash[]
轻松创建新的哈希,并为其提供一个包含一系列键/值对的数组。在这种情况下,
name
字段将从每个字段中删除。

如果我们将“优雅”理解为利用可重用抽象编写简洁代码的方式,我会这样写:

friends.each_with_object({}) do |f, o|
    f = f.dup
    o[f.delete :name] = f
end
require 'active_support/core_ext/hash'
require 'facets/hash'
friends.mash { |f| [f[:name], f.except(:name)] }
无需为这两个相当大的库添加gem依赖项,您始终可以在扩展库中实现各个方法。

如果我们将“优雅”理解为利用可重用抽象编写简洁代码的方式,我会这样写:

require 'active_support/core_ext/hash'
require 'facets/hash'
friends.mash { |f| [f[:name], f.except(:name)] }

无需为这两个相当大的库添加gem依赖项,您始终可以在扩展库中实现各个方法。

您仍然需要从属性:-)@tokland中删除名称。要解决此问题,您可以将其更改为
Hash[friends.map{f.delete(:name),f]}]
抱歉,但是IMHO
delete
是否定的,现在输入哈希也被修改了,一个算法不应该这样做。好的一点是,我添加了一个
dup
调用,这样每次迭代都会产生一个数据克隆。为什么你说
delete
在这里不好?@HansEngel:
delete
通常不好,因为它是一个命令式/破坏性操作,函数式/声明式编程通常使代码更容易理解和推理。Ruby没有非破坏性的删除功能,这就是为什么active_record除了之外还引入了
Hash。\n您仍然需要从属性中删除name:-)@tokland来修复这个问题,您可以将其更改为
Hash[friends.map{f.delete(:name),f]}
对不起,但是IMHO
delete
是一个不允许的,现在输入的Hash也被修改了,一个算法不应该这样做。好的一点-我添加了一个
dup
调用,这样每次迭代都会产生一个数据克隆。为什么你说
delete
在这里不好?@HansEngel:
delete
通常不好,因为它是一个命令式/破坏性操作,函数式/声明式编程通常使代码更容易理解和推理。Ruby没有非破坏性的删除功能,这就是为什么除了
之外,ActiveU记录引入了
Hash。