ruby - 将哈希数组转换为哈希哈希,由哈希的属性索引

标签 ruby arrays performance hash

我有一个散列数组,表示对象作为对 API 调用的响应。我需要从一些散列中提取数据,一个特定的键用作散列对象的 id。我想将数组转换为散列,其中键作为 ID,值作为具有该 ID 的原始散列。

我说的是:

api_response = [
  { :id => 1, :foo => 'bar' },
  { :id => 2, :foo => 'another bar' },
  # ..
]

ideal_response = {
  1 => { :id => 1, :foo => 'bar' },
  2 => { :id => 2, :foo => 'another bar' },
  # ..
}

我可以想到两种方法。

  1. 将数据映射到ideal_response(下)
  2. 使用 api_response.find { |x| x[:id] == i } 我需要访问的每条记录。
  3. 一种我不知道的方法,可能涉及一种使用 map 原生构建哈希的方法。

我的映射方法:

keys = data.map { |x| x[:id] }
mapped = Hash[*keys.zip(data).flatten]

我不禁觉得有一种更高效、更整洁的方法可以做到这一点。当需要访问的记录数量非常少时,选项 2 的性能非常好。映射在这里表现出色,但当响应中有大量记录时它开始崩溃。值得庆幸的是,我预计不会有超过 50-100 条记录,因此映射就足够了。

在 Ruby 中是否有更智能、更简洁或更高效的方法来执行此操作?

最佳答案

ruby <= 2.0

> Hash[api_response.map { |r| [r[:id], r] }]
#=> {1=>{:id=>1, :foo=>"bar"}, 2=>{:id=>2, :foo=>"another bar"}} 

然而,Hash::[]非常丑陋,打破了通常的从左到右的 OOP 流程。这就是为什么 Facets建议Enumerable#mash :

> require 'facets'
> api_response.mash { |r| [r[:id], r] }
#=> {1=>{:id=>1, :foo=>"bar"}, 2=>{:id=>2, :foo=>"another bar"}} 

这个基本抽象(将可枚举值转换为哈希值)很久以前就被要求包含在 Ruby 中,唉,without luck .

请注意,您的用例由 Active Support 涵盖:Enumerable#index_by

ruby >= 2.1

[更新] 仍然不喜欢 Enumerable#mash,但现在我们有 Array#to_h .它创建了一个中间数组,但总比没有好:

> object = api_response.map { |r| [r[:id], r] }.to_h

关于ruby - 将哈希数组转换为哈希哈希,由哈希的属性索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4753930/

相关文章:

.net - 拥有多个 DLL 好还是单个大 DLL 好?

ruby - 没有轨道的 ActiveRecord 时区

ruby - 如何编写仅在第一个和最后一个位置删除字符的 ruby​​ 正则表达式?

ruby-on-rails - 从另一个 gem 覆盖一个 gem 内的方法

javascript - 如何在 Typescript 中分隔数组

javascript - 如何在javascript中不使用.join()将数组转换为没有逗号并用空格分隔的字符串?

javascript - JSON 数据到 Javascript 数组未定义

属性访问的 Javascript 性能 : undefined vs false

ruby-on-rails - rails 中是否有 options_for_select 的分隔符?

c - 如何解析不能完全放入内存 RAM 中的文件