Ruby 1.9正则表达式作为哈希键

我正在尝试这个例子myhash = {/(\d+)/ => "hello"}ruby 1.9.2p136(2010-12-25)[i386-mingw32]
它没有按预期工作(编辑:因为事实certificate它不应该像我期望的那样工作):

 irb(main):004:0> myhash = {/(\d+)/ => "hello"} => {/(\d+)/=>"Hello"} irb(main):005:0> myhash[2222] => nil irb(main):006:0> myhash["2222"] => nil 

在rubular中 ,在ruby1.8.7上, 正则表达式起作用。
我错过了什么?

如果没有一些额外的代码,它将无法工作,因为您正在将Regexp对象与Integer或String对象进行比较。 它们不是平等的,也不是平等的。 它们匹配,但需要更改Hash类代码。

 irb(main):001:0> /(\d+)/.class => Regexp irb(main):002:0> 2222.class => Fixnum irb(main):003:0> '2222'.class => String irb(main):004:0> /(\d+)/==2222 => false irb(main):007:0> /(\d+)/=='2222' => false irb(main):009:0> /(\d+)/.equal?'2222' => false irb(main):010:0> /(\d+)/.equal?2222 => false 

你必须迭代哈希并使用=〜之类的东西:

  hash.each do |k,v| unless (k=~whatever.to_s).nil? puts v end end 

或者将Hash类更改为try =〜以及正常匹配条件。 (我认为最后一个选项很难,在mri中Hash类似乎有很多C代码)

你在寻找这种行为吗?

 myhash = Hash.new{|h,k| h[k] = 'hello' if k =~ /(\d+)/} p myhash['aaa'] #=> nil p myhash #=> {} p myhash['1234'] #=>" hello" p myhash #=> {"1234"=>"hello"} 

你可以将Jean的答案放在default_proc中

 MAP = { /1/ => "one", /2/ => "two", /\d/ => "number" } MAP.default_proc = lambda do |hash, lookup| hash.each_pair do |key, value| return value if key =~ lookup end return nil end p MAP["2"] #=> "two" p MAP[44] #=> "number" 

我从未想过使用正则表达式作为哈希键。 老实说,我不确定这是否应该有效,也不确定它应该如何工作。

无论如何,有两个想法:

  1. 在您尝试查找项目时,您使用hash ,但哈希名为myhash
  2. 如果我玩它,我得到这些结果:

     hektor ~ ❯❯ irb >> myhash = {/(\d+)/ => "hello"} => {/(\d+)/=>"hello"} >> myhash['2222'] => nil >> myhash[2222] => nil >> myhash[/(\d+)/] => "hello" 

这是使用Ruby 1.9.2-p180。

好的,检查过,这是有效的:

 myhash = {/foo/ => "hello"} myhash[/foo/] # => "hello" 

查找位于键上 ,键是正则表达式,而不是该正则表达式的许多潜在匹配之一。

现在有一个名为Hashie的gem提供此function(以及更多): https : //github.com/intridea/hashie#rash

它提供了一个名为Rash(regex-hash的缩写)的数据结构,可以像这样使用

 myhash = {/(\d+)/ => "hello"} rash = Hashie::Rash.new(myhash) >> rash["2222"] => "hello" 

它真的试图将密钥与正则表达式匹配,因此除非将它们转换为字符串,否则数字键将无法工作,您可以通过将Rashinheritance到您自己的类中来轻松完成