将类似于“each”的方法添加到从Hash继承的Ruby类中

将类似于“each”的方法添加到从Hash继承的Ruby类中,ruby,hash,Ruby,Hash,我想创建一个行为类似于标准Ruby哈希的类,并加入一些额外的访问方法。例如,假设: class SpecificHash < Hash def initialize (1..20).each do |num| self[num] = "value #{num.to_s}" end end end 我有几件事想做。使用一个简化的示例,我将如何为奇数键创建定义方法允许我调用: sh = SpecificHash.new sh.odd_keys { |k,

我想创建一个行为类似于标准Ruby哈希的类,并加入一些额外的访问方法。例如,假设:

class SpecificHash < Hash
  def initialize 
    (1..20).each do |num|
      self[num] = "value #{num.to_s}"
    end
  end
end
我有几件事想做。使用一个简化的示例,我将如何为奇数键创建定义方法允许我调用:

sh = SpecificHash.new
sh.odd_keys { |k,v| puts k }

让它像each方法一样工作,但只包含键为奇数的键/值对吗?

我相信这样的说法:

class SpecificHash < Hash
  def odd
    each do |k, v|
      yield(k, v) if k.odd?
    end
  end
end

将此方法添加到类中应该有效:

def odd
  return enum_for(:odd) unless block_given?
  each do |k, v|
    if k.respond_to?(:odd?) && k.odd?
      yield k, v
    end
  end
end
第一行是非常标准的实践,它允许您在块未传递到方法时返回枚举数,就像每个块一样。它可以实现以下功能:

hash.odd.select { ... }

我看不出为您的用例定义类的目的。一个枚举器实例似乎就足以满足您的需要

sh = (1..20).lazy
sh.map{|k| [k, "value #{k}"]}.to_h # => ...
sh.each{|k| puts k} # => ...
sh.select(&:odd?).each{|k| puts k} # => ...

是的,这是一个更好的答案!我意识到这很奇怪?是一种检查整数是否为奇数的方法。我已经更新了这个问题,将示例方法重命名为奇数键,以区分两者。唯一需要更改的是def odd到def odd_键,并返回enum_for:odd,除非给出了block_,这是否正确?要返回:奇数密钥的枚举,除非给出了块?和hash.odd.select{…}到hash.odd_keys.select{…}?是的,听起来你正确地识别了方法名出现在我的答案中的三个地方,你需要更改所有这些。我应该更清楚,具体的用例只是一个例子。我真正想要的是从基于过滤的散列中生成每种类型输出的技术。例如,一个包含按ID索引的人员列表的散列,我希望在其中进行方法调用,以根据每个人员的属性返回不同的子集。我试图简化这个例子,但可能做得有点过头了。不过,最好使用惰性枚举器。您可以从散列或数组中生成惰性枚举数。它允许您添加一系列方法来创建子集,而无需创建中间数组/散列,因此非常有效。
sh = (1..20).lazy
sh.map{|k| [k, "value #{k}"]}.to_h # => ...
sh.each{|k| puts k} # => ...
sh.select(&:odd?).each{|k| puts k} # => ...