Ruby 将哈希数组转换为哈希的哈希,由哈希的属性索引
我有一个哈希数组,表示对象作为对API调用的响应。我需要从一些散列中提取数据,一个特定的键用作散列对象的id。我想将数组转换成一个散列,其中键作为id,值作为原始散列,id为 下面是我要说的:Ruby 将哈希数组转换为哈希的哈希,由哈希的属性索引,ruby,arrays,performance,hash,Ruby,Arrays,Performance,Hash,我有一个哈希数组,表示对象作为对API调用的响应。我需要从一些散列中提取数据,一个特定的键用作散列对象的id。我想将数组转换成一个散列,其中键作为id,值作为原始散列,id为 下面是我要说的: api_response = [ { :id => 1, :foo => 'bar' }, { :id => 2, :foo => 'another bar' }, # .. ] ideal_response = { 1 => { :id => 1,
api_response = [
{ :id => 1, :foo => 'bar' },
{ :id => 2, :foo => 'another bar' },
# ..
]
ideal_response = {
1 => { :id => 1, :foo => 'bar' },
2 => { :id => 2, :foo => 'another bar' },
# ..
}
我有两种方法可以考虑这样做
理想的\u响应
(以下)api_response.find{x|x[:id]==i}
map
以本机方式构建哈希的方法keys = data.map { |x| x[:id] }
mapped = Hash[*keys.zip(data).flatten]
我忍不住觉得有一种更高效、更整洁的方法可以做到这一点。当需要访问的记录数量非常少时,选项2的性能非常好。映射在这里非常出色,但当响应中有大量记录时,映射就开始崩溃。谢天谢地,我不希望有超过50-100条记录,所以映射就足够了
在Ruby中有没有一种更智能、更整洁或更高效的方法呢?类似于:
ideal_response = api_response.group_by{|i| i[:id]}
#=> {1=>[{:id=>1, :foo=>"bar"}], 2=>[{:id=>2, :foo=>"another bar"}]}
它使用Enumerable的group_by
,它对集合起作用,返回您想要的任何键值的匹配项。因为它希望找到匹配键值命中的多个匹配项,所以会将它们附加到数组中,因此最终会得到哈希数组的哈希值。如果需要,可以剥离内部数组,但如果两个哈希ID发生冲突,则可能会有覆盖内容的风险group_by
避免使用内部数组
访问特定元素很容易:
ideal_response[1][0] #=> {:id=>1, :foo=>"bar"}
ideal_response[1][0][:foo] #=> "bar"
你在问题末尾的表现方式是另一种有效的方式。两者都相当快速和优雅 Ruby为此,我可能会:
ideal_response = api_response.each_with_object(Hash.new) { |o, h| h[o[:id]] = o }
块中的多个括号不是非常漂亮,但它只需对api_响应进行一次迭代即可达到效果。这在性能和整洁性方面比我使用的映射要好,但是通过
data[id][0]
或data[id]访问记录。首先有点麻烦。不过,我在这一点上吹毛求疵。让我们看看是否还有其他人愿意参加比赛。这是因为可能会遇到重复的钥匙<代码>分组依据
是为未知数据的安全而设计的通用例程。拥有特定于应用程序的知识,例如知道您永远不会遇到重复以及随后的密钥冲突和数据丢失,将允许将数据结构简化一个级别。
> require 'facets'
> api_response.mash { |r| [r[:id], r] }
#=> {1=>{:id=>1, :foo=>"bar"}, 2=>{:id=>2, :foo=>"another bar"}}
> object = api_response.map { |r| [r[:id], r] }.to_h
ideal_response = api_response.each_with_object(Hash.new) { |o, h| h[o[:id]] = o }