红宝石哈希键作为对象方法



是否有API,或者如何通过DOT(。)方法访问Hash键,例如是否存在对象。

这是一个示例:

data = [
  {
    key1: 'value1',
    key2: 'value2'
  },
  {
    key1: 'valuex',
    key2: 'valuey'
  },
  ...
]

如果我试图这样做:

data.collect(&:key1)

会得到此错误:

NoMethodError: undefined method `key1' for #<Hash:0x007fc2a7159188>

但是,这有效:

data.collect{|hs| hs[:key1]}

仅仅是因为它是符号而不是对象属性。有没有办法用符号来实现相同的行为,就好像它们是对象属性吗?

您可以将这些哈希包裹在OpenStruct中。尝试使用此代码:

data.map! { |hsh| OpenStruct.new(hsh) }
data.first.key1 # => "value1"

这是受 @spickerman的评论的启发。这是一个人可以做的,但可能不应该做。

您可以将自定义方法添加到Ruby的枚举模块:

module Enumerable
  def enum_send(:method, *args)
    send(:method) { |obj| obj.send(*args) }
  end
end

您可以致电

data.enum_send(:collect, :"[]", :key1)  ## [value1, valuex..]

或类似

的东西
data.enum_send(:each, :delete, :key2)  ## [{key1: value1}, {key1: valuex}..]

您可以用openscruct

包装对象
require 'ostruct'
data.map { |it| OpenStruct.new(it) }.collect(&:key1)

最新更新