Ruby 1.9 регулярное выражение в качестве хеш-ключа - PullRequest
11 голосов
/ 15 марта 2011

Я пытаюсь этот пример myhash = {/(\d+)/ => "hello"} с ruby ​​1.9.2p136 (2010-12-25) [i386-mingw32] .
Он не работает должным образом (edit: как оказалось, он не должен работать так, как я ожидал):

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 .
Что мне не хватает?

Ответы [ 5 ]

12 голосов
/ 15 марта 2011

Вы ищете это поведение?

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"}
9 голосов
/ 15 марта 2011

Он не будет работать без дополнительного кода, так как вы сравниваете объект 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

или изменить хэшкласс, чтобы попробовать = ~ в дополнение к нормальным условиям соответствия.(Я думаю, что последний вариант будет трудным, в mri класс Hash, похоже, содержит много кода C)

3 голосов
/ 09 декабря 2013

Вы можете поместить ответ Джин в 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 голос
/ 15 марта 2011

Мне никогда не приходило в голову использовать регулярное выражение в качестве хеш-ключа.Я, честно говоря, не уверен, что это должно работать, и точно, как это будет работать, если оно должно.

В любом случае, две мысли:

  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"

Поиск на ключ , иключ - это регулярное выражение, а не одно из многих возможных совпадений этого регулярного выражения.

0 голосов
/ 31 мая 2018

Теперь существует гем под названием Hashie, который предоставляет эту функцию (и многое другое): https://github.com/intridea/hashie#rash

Он предоставляет структуру данных с именем Rash (сокращение от regex-hash), которую можно использовать следующим образом

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

>> rash["2222"]
=> "hello"

Он действительно пытается сопоставить ключ с регулярными выражениями, поэтому числовые ключи не будут работать, если вы не преобразуете их в строку, что вы можете легко сделать, унаследовав Rash в своем собственном классе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...