关于Ruby收集方法的问题

我有一系列哈希

例如:

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' 

我想知道是否有类似的快捷方式来执行上述操作。

我相信你当前的代码cars.collect{|c| c[:company]} cars.collect{|c| c[:company]}是最好的方法,如果你枚举任意数组。 您将通过&快捷方式传入的方法必须是在Hash上定义的方法,因为数组中的每个对象都是Hash类型。 由于没有为Hash定义company方法,因此您会收到“未定义方法’公司’”错误。

如果您在汽车数组上运行,则可以使用cars.collect(&:company) ,因为传递到collect块的每个对象都是Car类型(具有公司方法可用)。 所以也许你可以修改你的代码,以便你使用汽车数组。

您可以将哈希值转换为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"] 

在你的情况下不可能使用,因为在收集你使用方法[]和论点:公司。 建筑&:公司采用标签:company并转换为Proc ,因此它只是一个参数 – 方法的名称。

不幸的是,Ruby哈希不能做到这一点。 另一方面,Clojure映射具有返回相应值的每个键的函数,如果你这么倾向就很容易做到(你还应该添加相应的respond_to?方法):

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

注意:我不是建议这个,我只是说这是可能的。

另一个你不应该使用的可怕的monkeypatch:

 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)