2011-03-29 8 views
3

私はハッシュ質問収集方法

のEG配列を有する:

cars = [{:company => "Ford", :type => "SUV"}, 
     {:company => "Honda", :type => "Sedan"}, 
     {:company => "Toyota", :type => "Sedan"}] 

# i want to fetch all the companies of the cars 
cars.collect{|c| c[:company]} 
# => ["Ford", "Honda", "Toyota"] 

# i'm lazy and i want to do something like this 
cars.collect(&:company) 
# => undefined method `company' 

上記を実行するために同様のショートカットがある場合、私は思っていました。

+0

を私は怠け者だとは思いません。それは簡潔です。 –

答えて

6

私はあなたの現在のコードcars.collect{|c| c[:company]}は、任意の配列で列挙している場合は最良の方法だと思います。 &ショートカットで渡すメソッドは、配列内の各オブジェクトがHashの型であるため、Hashで定義されたメソッドでなければなりません。 Hashについてcompanyメソッドが定義されていないため、「未定義メソッド 'company'」エラーが発生します。あなたがが車のアレイ上で動作している場合collectブロックに渡される各オブジェクトは、(利用可能な会社法を持っている)タイプCarであろうので

あなたは、cars.collect(&:company)を使用することができます。だから多分あなたはあなたのコードを変更して、代わりにCarsの配列を使うことができます。

+0

うん、それは理にかなっている。それは私が当初考えていたものです。ありがとう! –

0

収集では、方法[]と引数:会社を使用するため、使用することはできません。構成&:会社はラベル:companyを受け取り、Procに変換します。そのため、メソッドの名前は1つだけです。

0

残念ながら、Rubyハッシュではできません。

>> class Hash 
.. def method_missing(m) 
..  self.has_key?(m) ? self[m] : super 
..  end 
.. end #=> nil 
>> cars.collect(&:company) #=> ["Ford", "Honda", "Toyota"] 
>> cars.collect(&:compay) 
NoMethodError: undefined method `compay' for {:type=>"SUV", :company=>"Ford"}:Hash 

注:一方、Clojureのマップは、あなたは(あなたはまた、対応するrespond_to?メソッドを追加する必要があります)ので、傾斜している場合は行うのに十分簡単だろう、対応する値を返す各キーのための機能を持っている私は、これをアドバイスしないで、私はそれが可能であると言っているだけです。

5

ハッシュをOpenStructsに変換できます。

require 'ostruct' 
cars = [{:company => "Ford", :type => "SUV"}, 
     {:company => "Honda", :type => "Sedan"}, 
     {:company => "Toyota", :type => "Sedan"}] 
cars = cars.map{|car| OpenStruct.new(car)} 

p cars.map(&:company) 
#=> ["Ford", "Honda", "Toyota"] 
+0

それはクールだ! OpenStructsについて知りませんでした。 –

0

あなたが本当に使用してはならないもう一つの恐ろしいモンキーパッチ:

class Symbol 
    def to_proc 
    if self.to_s =~ /bracket_(.*)/ 
     Proc.new {|x| x[$1.to_sym]} 
    else 
     Proc.new {|x| x.send(self)} 
    end 
    end 
end 

cars = [{:company => "Ford", :type => "SUV"}, 
     {:company => "Honda", :type => "Sedan"}, 
     {:company => "Toyota", :type => "Sedan"}] 

cars.collect(&:bracket_company)