问题描述
我有哈希值的数组重新presenting对象作为一个API调用的响应。我需要从一些哈希提取数据,以及一个特定的键用作哈希对象的ID。我想数组转换成与密钥作为标识,和值作为原始哈希与ID的哈希值。
下面就是我说的:
api_response = [
{:ID => 1,:富=> 酒吧},
{:ID => 2,:富=> 另一个酒吧},
#..
]ideal_response = {
1 => {:ID => 1,:富=> 酒吧},
2 => {:ID => 2,:富=> 另一个酒吧},
#..
}
有我能想到这样做的两种方式。
- 地图数据到
ideal_response
(图) - 使用
api_response.find {| X | X [:编号] == I}
每个记录我需要访问 。 - 我不知道,可能涉及使用
地图
来建立一个哈希,本机的方式方法。
我的映射方式:
键= {Data.Map中| X | X [:ID]}
映射=散列[* keys.zip(数据).flatten]
我不禁觉得自己有这样做的更好的性能,更整洁的方式。当存在的需要被访问的记录一个很小的数值选项2是非常高性能的。映射擅长在这里,但它开始分解的时候也有很多的响应记录。值得庆幸的是,我不认为会有超过50-100的记录,所以映射就足够了。
有没有更聪明,更整洁,更高性能的红宝石这样的方式?
哈希[api_response.map {| R | [R [:编号],R]}]
#{1 => {:ID => 1:富=>中的酒吧},2 => {:ID => 2,:富=>中另一栏}}
不过,是pretty丑陋,打破了通常的左到右OOP流。这就是为什么提出的:
要求'面'
api_response.mash {| R | [R [:编号],R]}
#{1 => {:ID => 1:富=>中的酒吧},2 => {:ID => 2,:富=>中另一栏}}
这基本的抽象(转换为可枚举哈希)被要求早就被列入红宝石,唉,的。
[更新] 还增加了可枚举#捣烂
,但开发者没有爱情的了Ruby 2.1。不理想,但总比没有好:
#红宝石2.1
api_response.map {| R | [R [:编号],R]} .to_h
I've got an array of hashes representing objects as a response to an API call. I need to pull data from some of the hashes, and one particular key serves as an id for the hash object. I would like to convert the array into a hash with the keys as the ids, and the values as the original hash with that id.
Here's what I'm talking about:
api_response = [
{ :id => 1, :foo => 'bar' },
{ :id => 2, :foo => 'another bar' },
# ..
]
ideal_response = {
1 => { :id => 1, :foo => 'bar' },
2 => { :id => 2, :foo => 'another bar' },
# ..
}
There are two ways I could think of doing this.
- Map the data to the
ideal_response
(below) - Use
api_response.find { |x| x[:id] == i }
for each record I need to access. - A method I'm unaware of, possibly involving a way of using
map
to build a hash, natively.
My method of mapping:
keys = data.map { |x| x[:id] }
mapped = Hash[*keys.zip(data).flatten]
I can't help but feel like there is a more performant, tidier way of doing this. Option 2 is very performant when there are a very minimal number of records that need to be accessed. Mapping excels here, but it starts to break down when there are a lot of records in the response. Thankfully, I don't expect there to be more than 50-100 records, so mapping is sufficient.
Is there a smarter, tidier, or more performant way of doing this in Ruby?
Hash[api_response.map { |r| [r[:id], r] }]
# {1=>{:id=>1, :foo=>"bar"}, 2=>{:id=>2, :foo=>"another bar"}}
However, Hash::[] is pretty ugly and breaks the usual left-to-right OOP flow. That's why Facets proposed Enumerable#mash:
require 'facets'
api_response.mash { |r| [r[:id], r] }
# {1=>{:id=>1, :foo=>"bar"}, 2=>{:id=>2, :foo=>"another bar"}}
This basic abstraction (convert enumerables to hashes) was asked to be included in Ruby long ago, alas, without luck.
[UPDATE] Still no love for Enumerable#mash
, but devs added Array#to_h to Ruby 2.1. Not ideal, but better than nothing:
# ruby 2.1
api_response.map { |r| [r[:id], r] }.to_h
这篇关于转换数组的哈希值,以一个哈希的哈希值,通过散列的属性索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!