Ruby-on-rails 从数组创建哈希的最简洁方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/412771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:52:41  来源:igfitidea点击:

Cleanest way to create a Hash from an Array

ruby-on-railsrubyarrayshash

提问by Daniel Beardsley

I seem to run into this very often. I need to build a Hash from an array using an attribute of each object in the array as the key.

我似乎经常遇到这种情况。我需要使用数组中每个对象的属性作为键从数组构建一个哈希。

Lets say I need a hash of example uses ActiveRecord objecs keyed by their ids Common way:

假设我需要一个散列示例,使用 ActiveRecord 对象以它们的 id 为键的常用方式:

ary = [collection of ActiveRecord objects]
hash = ary.inject({}) {|hash, obj| hash[obj.id] = obj }

Another Way:

其它的办法:

ary = [collection of ActiveRecord objects]
hash = Hash[*(ary.map {|obj| [obj.id, obj]}).flatten]

Dream Way: I could and might create this myself, but is there anything in Ruby or Rails that will this?

Dream Way:我可以也可能自己创建它,但是 Ruby 或 Rails 中是否有任何东西可以做到这一点?

ary = [collection of ActiveRecord objects]
hash = ary.to_hash &:id
#or at least
hash = ary.to_hash {|obj| obj.id}

回答by August Lilleaas

There is already a method in ActiveSupport that does this.

ActiveSupport 中已经有一个方法可以做到这一点。

['an array', 'of active record', 'objects'].index_by(&:id)

And just for the record, here's the implementation:

只是为了记录,这是实现:

def index_by
  inject({}) do |accum, elem|
    accum[yield(elem)] = elem
    accum
  end
end

Which could have been refactored into (if you're desperate for one-liners):

可以重构为(如果您迫切需要单行代码):

def index_by
  inject({}) {|hash, elem| hash.merge!(yield(elem) => elem) }
end

回答by zed_0xff

a shortest one?

最短的?

# 'Region' is a sample class here
# you can put 'self.to_hash' method into any class you like 

class Region < ActiveRecord::Base
  def self.to_hash
    Hash[*all.map{ |x| [x.id, x] }.flatten]
  end
end

回答by Fedcomp

In case someone got plain array

如果有人得到普通数组

arr = ["banana", "apple"]
Hash[arr.map.with_index.to_a]
 => {"banana"=>0, "apple"=>1}

回答by ewalshe

You can add to_hash to Array yourself.

您可以自己将 to_hash 添加到 Array 中。

class Array
  def to_hash(&block)
    Hash[*self.map {|e| [block.call(e), e] }.flatten]
  end
end

ary = [collection of ActiveRecord objects]
ary.to_hash do |element|
  element.id
end

回答by Lolindrath

Install the Ruby Facets Gemand use their Array.to_h.

安装Ruby Facets Gem并使用它们的Array.to_h