Ruby 1.9 regex как хэш-ключ
Я пытаюсь использовать этот пример myhash = {/(\d+)/ => "hello"}
с ruby 1.9.2p136 (2010-12-25) [i386-mingw32].
Он работает не так, как ожидалось (редактирование: как оказалось, он не должен работать так, как я ожидал):
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, работает regex.
Что мне не хватает?
Ответы
Ответ 1
Он не будет работать без какого-либо дополнительного кода, так как вы сравниваете объект 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, чтобы попробовать = ~ в дополнение к нормальным условиям сопоставления. (Я думаю, что последний вариант будет сложным, в mri класс Hash, похоже, содержит много кода C)
Ответ 2
Вы ищете это поведение?
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
Вы можете поместить ответ 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"
Ответ 4
Мне никогда не приходило в голову, чтобы использовать регулярное выражение как хэш-ключ. Я честно не уверен, что это сработает, и точно, как это будет работать, если это нужно.
В любом случае, две мысли:
- В ваших попытках поиска элемента вы используете
hash
, но хэш называется myhash
.
-
Если я играю с ним, я получаю следующие результаты:
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"
Поиск выполняется по ключу, а ключ представляет собой регулярное выражение, а не одно из многих возможных совпадений этого регулярного выражения.