web-dev-qa-db-ja.com

配列からハッシュを作成する最もクリーンな方法

私はこれに頻繁に遭遇するようです。配列内の各オブジェクトの属性をキーとして使用して、配列からハッシュを作成する必要があります。

例のハッシュが必要だとしましょう。IDでキー設定されたActiveRecordオブジェクトを使用します。一般的な方法:

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

別の方法:

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

ドリームウェイ:これを自分で作成することもできますが、RubyまたはRailsに何かありますか?

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

ActiveSupportには、これを行うメソッドがすでにあります。

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

念のため、実装は次のとおりです。

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

これはリファクタリングされた可能性があります(ワンライナーが必要な場合):

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

最短のもの?

# '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
9
zed_0xff

誰かがプレーン配列を取得した場合

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

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
5
ewalshe

Ruby Facets Gem をインストールし、 Array.to_h を使用します。

0
Lolindrath