0

鉴于我有一个响应一些方法的对象。我想在哈希中收集其中一些,我总是这样写一个片段。

class Person
  # ...

  def some_selected_attributes
    attrs = {}
    [:first_name, :last_name, :zip].each do |attr|
      attrs[attr] = self.__send__(attr)
    end
    attrs
  end
end

我相信有一种更优雅的方式来做到这一点。

:wq!

4

3 回答 3

2

由于只有三个属性,我认为没有理由不直接编写它:

def some_selected_attributes
  {
    first_name: first_name,
    last_name: last_name,
    zip: zip
  }
end

你也可以这样做inject

def some_selected_attributes
  [:first_name, :last_name, :zip].inject({}) do |hash, attr|
    hash[attr] = __send__ attr
    hash
  end
end

另一种选择,使用Hash[]

def some_selected_attributes
  Hash[[:first_name, :last_name, :zip].map {|attr| [attr, __send__ attr] }]
end
于 2012-04-05T23:41:08.020 回答
1

如果你真的想要一个哈希,LBg 给了你一些很好的模式。但是您可能需要考虑制作小型结构对象而不是原始哈希。结构的行为类似于用于索引和枚举的哈希,但也具有访问器方法,因此它们可以与发送和点表示法一起使用。

class Person
  # ...
  SomeSelectedPersonAttrs = Struct.new :first_name, :last_name, :zip

  def some_selected_attributes
    SomeSelectedPersonAttrs[ * SomeSelectedPersonAttrs.members.map{|a| send a } ]
  end

end

pa = person.some_selected_attributes
pa.first_name    # => "Joe"
pa[:first_name]  # => "Joe"
pa['first_name'] # => "Joe"
p.zip = 12345    # sets zip to 12345
p[:zip] = 12345
p['zip'] = 12345

pa.values       # => ["Joe","Blow",12345]
pa.each_pair {|k,v| ... }
于 2012-04-06T02:29:56.383 回答
-1

我认为有更好的方法来完成你想要做的事情。编写一个方法来返回类中已经存在的参数散列没有多大意义。您可以使用 attr_accessor 使实例变量或方法可访问:

class Person
  attr_accessor :first_name, :last_name, :zip

end

那么你就不需要 some_selected_attributes() 方法了。您可以直接访问变量或方法:

p = Person.new
p.first_name  # => value of first_name

如果你想要一个哈希,你可以创建它:

p = Person.new
hash = {:first_name => p.first_name, :last_name => p.last_name, :zip => p.zip }

我也不确定您为什么要构建此哈希。似乎这是一种更“面向对象”的方式来完成您想要做的任何事情(通过将整个对象作为参数传递)。

我建议不要使用选定字段的散列,而是使用整个对象。

于 2012-04-06T03:29:34.713 回答