转换数组的哈希值,以一个哈希的哈希值,通过散列的属性索引 [英] Convert array-of-hashes to a hash-of-hashes, indexed by an attribute of the hashes

查看:362
本文介绍了转换数组的哈希值,以一个哈希的哈希值,通过散列的属性索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有哈希值的数组重新presenting对象作为一个API调用的响应。我需要从一些哈希提取数据,以及一个特定的键用作哈希对象的ID。我想数组转换成与密钥作为标识,和值作为原始哈希与ID的哈希值。

下面就是我说的:

  api_response = [
  {:ID => 1,:富=> 酒吧},
  {:ID => 2,:富=> 另一个酒吧},
  #..
]ideal_response = {
  1 => {:ID => 1,:富=> 酒吧},
  2 => {:ID => 2,:富=> 另一个酒吧},
  #..
}

有我能想到这样做的两种方式。


  1. 地图数据到 ideal_response (图)

  2. 使用 api_response.find {| X | X [:编号] == I} 每个记录我需要访问

  3. 我不知道,可能涉及使用地图来建立一个哈希,本机的方式方法。

我的映射方式:

 键= {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,:富=>中另一栏}}

这基本的抽象(转换为可枚举哈希)被要求早就被列入红宝石,唉,的没有运气

[更新] 还增加了可枚举#捣烂,但开发者没有爱情的阵列#to_h 了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.

  1. Map the data to the ideal_response (below)
  2. Use api_response.find { |x| x[:id] == i } for each record I need to access.
  3. 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

这篇关于转换数组的哈希值,以一个哈希的哈希值,通过散列的属性索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆