I am trying this example myhash = {/(\d+)/ => "hello"}
with ruby 1.9.2p136 (2010-12-25) [i386-mingw32].
It doesn't work as expected (edit: as it turned out it shouldn't work as I was expecting):
我正在使用ruby 1.9.2p136 (2010-12-25) [i386-mingw32]尝试这个示例myhash = {/(\d+)/ =>“hello”}。它不像预期的那样工作(编辑:原来它不应该像我预期的那样工作):
irb(main):004:0> myhash = {/(\d+)/ => "hello"}
=> {/(\d+)/=>"Hello"}
irb(main):005:0> myhash[2222]
=> nil
irb(main):006:0> myhash["2222"]
=> nil
In Rubular which is on ruby1.8.7 the regex works.
What am I missing?
在ruby1。7上的rubble, regex就会工作。我缺少什么?
5 个解决方案
#1
9
It will not work without some extra code, as it is you are comparing a Regexp object with either an Integer or a String object. They won't be value equal, nor identity equal. They would match but that requires changes to the Hash class code.
如果没有一些额外的代码,它将无法工作,因为您正在将Regexp对象与一个整数或一个字符串对象进行比较。它们不相等,也不相等。它们会匹配,但这需要对哈希类代码进行修改。
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
you would have to iterate the hash and use =~ in something like:
您将不得不迭代散列并在如下内容中使用=~:
hash.each do |k,v|
unless (k=~whatever.to_s).nil?
puts v
end
end
or change the Hash class to try =~ in addition to the normal matching conditions. (I think that last option would be difficult, in mri the Hash class seems to have a lot of C code)
或者,除了正常的匹配条件外,更改哈希类尝试=~。(我认为最后一个选项会很困难,在mri中哈希类似乎有很多C代码)
#2
12
Are you looking for this behaviour?
你在寻找这种行为吗?
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"}
#3
3
You can put Jean's answer in a default_proc
你可以把简的答案放在一个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"
#4
1
It never occurred to me to use a regex as a hash key. I'm honestly not sure if that should work, nor exactly how it would work if it should.
我从未想到过要使用regex作为散列键。老实说,我不确定这是否可行,也不确定如果可行,它将如何运作。
In any case, two thoughts:
无论如何,有两个想法:
- In your attempts to lookup the item, you use
hash
, but the hash is namedmyhash
. - 在尝试查找项时,使用散列,但该散列被命名为myhash。
-
If I play around with it, I get these results:
如果我玩这个游戏,我就会得到这样的结果:
hektor ~ ❯❯ irb >> myhash = {/(\d+)/ => "hello"} => {/(\d+)/=>"hello"} >> myhash['2222'] => nil >> myhash[2222] => nil >> myhash[/(\d+)/] => "hello"
This is using Ruby 1.9.2-p180.
这是使用Ruby 1.9.2-p180。
Ok, checked and here's what works:
好的,检查一下
myhash = {/foo/ => "hello"}
myhash[/foo/] # => "hello"
The lookup is on the key, and the key is a regex, not one of the many potential matches of that regex.
查找位于键上,键是regex,而不是该regex的许多潜在匹配之一。
#5
0
There is now a gem called Hashie that provides this feature (and much more): https://github.com/intridea/hashie#rash
现在有一个叫做Hashie的gem提供了这个特性(以及更多的特性):https://github.com/好奇/ Hashie #rash
It provides a data structure called Rash (short for regex-hash) that can be used like this
它提供了一个名为Rash (regex散列的简称)的数据结构,可以像这样使用
myhash = {/(\d+)/ => "hello"}
rash = Hashie::Rash.new(myhash)
>> rash["2222"]
=> "hello"
It really tries to match the key against the regexes so numeric keys won't work unless you convert them to string, which you can do easily by inheriting Rash into your own class
它确实试图将键与regexes匹配,因此除非将数字键转换为string,否则数字键将不起作用
#1
9
It will not work without some extra code, as it is you are comparing a Regexp object with either an Integer or a String object. They won't be value equal, nor identity equal. They would match but that requires changes to the Hash class code.
如果没有一些额外的代码,它将无法工作,因为您正在将Regexp对象与一个整数或一个字符串对象进行比较。它们不相等,也不相等。它们会匹配,但这需要对哈希类代码进行修改。
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
you would have to iterate the hash and use =~ in something like:
您将不得不迭代散列并在如下内容中使用=~:
hash.each do |k,v|
unless (k=~whatever.to_s).nil?
puts v
end
end
or change the Hash class to try =~ in addition to the normal matching conditions. (I think that last option would be difficult, in mri the Hash class seems to have a lot of C code)
或者,除了正常的匹配条件外,更改哈希类尝试=~。(我认为最后一个选项会很困难,在mri中哈希类似乎有很多C代码)
#2
12
Are you looking for this behaviour?
你在寻找这种行为吗?
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"}
#3
3
You can put Jean's answer in a default_proc
你可以把简的答案放在一个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"
#4
1
It never occurred to me to use a regex as a hash key. I'm honestly not sure if that should work, nor exactly how it would work if it should.
我从未想到过要使用regex作为散列键。老实说,我不确定这是否可行,也不确定如果可行,它将如何运作。
In any case, two thoughts:
无论如何,有两个想法:
- In your attempts to lookup the item, you use
hash
, but the hash is namedmyhash
. - 在尝试查找项时,使用散列,但该散列被命名为myhash。
-
If I play around with it, I get these results:
如果我玩这个游戏,我就会得到这样的结果:
hektor ~ ❯❯ irb >> myhash = {/(\d+)/ => "hello"} => {/(\d+)/=>"hello"} >> myhash['2222'] => nil >> myhash[2222] => nil >> myhash[/(\d+)/] => "hello"
This is using Ruby 1.9.2-p180.
这是使用Ruby 1.9.2-p180。
Ok, checked and here's what works:
好的,检查一下
myhash = {/foo/ => "hello"}
myhash[/foo/] # => "hello"
The lookup is on the key, and the key is a regex, not one of the many potential matches of that regex.
查找位于键上,键是regex,而不是该regex的许多潜在匹配之一。
#5
0
There is now a gem called Hashie that provides this feature (and much more): https://github.com/intridea/hashie#rash
现在有一个叫做Hashie的gem提供了这个特性(以及更多的特性):https://github.com/好奇/ Hashie #rash
It provides a data structure called Rash (short for regex-hash) that can be used like this
它提供了一个名为Rash (regex散列的简称)的数据结构,可以像这样使用
myhash = {/(\d+)/ => "hello"}
rash = Hashie::Rash.new(myhash)
>> rash["2222"]
=> "hello"
It really tries to match the key against the regexes so numeric keys won't work unless you convert them to string, which you can do easily by inheriting Rash into your own class
它确实试图将键与regexes匹配,因此除非将数字键转换为string,否则数字键将不起作用