3

別の列挙型またはハッシュを返すために列挙型を反復処理するメソッドが頻繁にあることがわかりました。これらのメソッドは、ほとんどの場合、次の単純な例のようになります。

  def build_hash(array)
    hash = {}
    array.each do |item|
      hash[ item[:id] ]= item
    end
    hash
  end

このアプローチは機能しますが、特に、戻り値が正しくなるようにループを一時オブジェクトでラップする必要なしに、これを行うためのよりクリーンな方法があるかどうか疑問に思うことがよくあります。

誰かがこれを行うための改善されたおよび/またはよりクリーンなおよび/またはより速い方法を知っていますか、またはこれはほとんど最良の方法ですか?

4

5 に答える 5

3

あなたの特定の例を考慮して、ここにいくつかの方法があります

arr = [{:id => 1, :name => :foo}, {:id => 2, :name => :bar}]

Hash[arr.map{ |o| [o[:id], o] }]
arr.each_with_object({}){ |o, h| h[o[:id]] = o }
arr.reduce({}){ |h, o| h[o[:id]] = o; h }
arr.reduce({}){ |h, o| h.merge o[:id] => o }

# each of these return the same Hash
# {1=>{:id=>1, :name=>:foo}, 2=>{:id=>2, :name=>:bar}} 
于 2013-03-01T19:27:21.223 に答える
1

この場合、次injectのようなものを使用して実行できます。

def build_hash(array)
  array.inject({}) { |init, item| init[item[:id]] = item; init }
end
于 2013-03-01T19:22:08.237 に答える
1
{}.tap { |h| array.each { |a| h[a[:id]] = a } }
于 2013-03-01T19:22:49.593 に答える
1

Arrayに変換する方法もありますHash

list_items = ["1", "Foo", "2", "Bar", "3" , "Baz"]

 hss = Hash[*list_items]
  • パラメータは偶数である必要があります。そうでない場合、奇数の引数を一連のキーと値のペアにマップできないため、致命的なエラーが発生します。

{"1" => "Foo"、 "2" => "Bar"、 "3" => "Baz"}

于 2013-03-01T19:43:40.430 に答える
1

ActiveSupportのを使用できますindex_by

あなたの例は取るに足らないものになります:

def build_hash(array)
  array.index_by{|item| item[:id]}
end

現在、Ruby 2.0であっても、Rubyでハッシュを作成するための優れた方法はありません。

Hash[]私はそれを非常に醜いと思いますが、あなたは使うことができます:

def build_hash(array)
  Hash[array.map{|item| [item[:id], item]}]
end

マッツを説得できれば、少なくとも次のことができます。

def build_hash(array)
  array.map{|item| [item[:id], item]}.to_h
end

ハッシュを作成する新しい方法については、他にもリクエストがあります。

于 2013-03-01T19:54:21.523 に答える