Ruby 有什么方法能够使 Hash 支持上范围?

pepsin · 2012年09月07日 · 最后由 cantin 回复于 2012年09月07日 · 2656 次阅读

比如这种写法:

hash = {(1..5) => "One To Five", (6..10) => "Six To Ten"} 然后调: hash[3]hash[4.1] 能够输出 One To Five

这两天偶尔会遇上这问题,输入是整数的话用include? 能够解决一下

其他情况目前只能想到要么 case when 组合,要么 if else 组合了, 条件一多看起来极其恶心。

class_eval下,但是发现这些貌似没法定义来着。

class hash alias get [] def [] key get self.keys.select{|k| k.include? key}.first end end

class Hash
  def flat_keys
    h = {}
    self.keys.each do |key|
      key.to_a.each{|k| h[k] = self[key]}
    end
    h
  end
end

hash = {(1..5) => "One To Five", (6..10) => "Six To Ten"}.flat_keys

#1 楼 @jjym 这个只是对应上整数而已,这个实现已经知道了。

需要的是能写出范围,然后在[]方法时能判断一个数是否在键所圈定范围内,如果是就返回值。

#2 楼 @pepsin 我上边画线就是这样,不过如果这样的话 hash 就没意义了。其实写个方法用 when..case 就行

#3 楼 @jjym 诶,疏忽了。以前试的时候发现included?貌似不支持对应 float,现在发现也可以,嘿嘿,谢谢啦。


class Hash
  def with(key)
    value = self[key]

    self[keys.find { |k| k.respond_to?(:include?) && k.include?(key) }] if value.nil?
  end 
end

hash = {(1..5) => "One To Five", (6..10) => "Six To Ten"}

puts hash.with(4.1123)

我重写不了 Hash 的 [ ] 方法,不知道你们是不是可以重写?

class Hash
  alias :with :[]

  def [](key)
    value = with key

    if value.nil?
      with(keys.find { |k| k.respond_to?(:include?) && k.include?(key) })
    end
  end
end

hash = {(1..5) => "One To Five", (6..10) => "Six To Ten"}

puts hash[3.222]
puts hash[9.99]

重新试了一下,应该可以

需要 登录 后方可回复, 如果你还没有账号请 注册新账号