Один лайнер вложил создание хеша в Ruby? (Я происхожу из Perl),

Я - человек Perl, и я сделал Хеши как это некоторое время:

my %date;

#Assume the scalars are called with 'my' earlier

$date{$month}{$day}{$hours}{$min}{$sec}++

Теперь я изучаю Ruby, и я до сих пор нашел, что использование этого дерева является способом сделать много ключей и значение. Там какой-либо путь состоит в том, чтобы использовать простой формат, который я использую с Perl с помощью одной строки?

 @date = {                                                                                                                                                                      
        month => {                                                                                                                                                                 
          day => {                                                                                                                                                                 
           hours => {                                                                                                                                                              
              min => {                                                                                                                                                             
                sec => 1                                                                                                                                                           
              }                                                                                                                                                                    
            }                                                                                                                                                                      
          }                                                                                                                                                                        
        }                                                                                                                                                                                                                                                                                                                                                     
      }                   
28
задан Flip 6 October 2016 в 11:18
поделиться

4 ответа

К сожалению, нет простого, практичного способа. Ruby-эквивалент был бы уродливым, уродливым чудовищем вроде:

((((@date[month] ||= {})[day] ||= {})[hours] ||= {})[min] ||= {})[sec] = 1

Есть способ назначить значения по умолчанию для отсутствующих ключей в хэшах, хотя:

@date = Hash.new { |hash, key| hash[key] = {} }

# @date[:month] is set to a new, empty hash because the key is missing.
@date[:month][:day] = 1

К сожалению, это не работает рекурсивно.

... если только вы не создадите его сами; ура Ruby!

class Hash
  def self.recursive
    new { |hash, key| hash[key] = recursive }
  end
end

@date = Hash.recursive
@date[month][day][hours][min][sec] = 1
# @date now equals {month=>{day=>{hours=>{min=>{sec=>1}}}}}

Однако имейте в виду, что все несброшенные значения теперь {}, а не nil.

48
ответ дан 28 November 2019 в 02:19
поделиться

Не похоже, что Ruby может делать автовивификацию с самого начала, но вы можете легко добавить эту функциональность. Поиск "ruby autovivification" в Google дает:

http://t-a-w.blogspot.com/2006/07/autovivification-in-ruby.html

Который содержит достойный пример того, как создать хэш, который будет работать так, как вам нужно.

ruby hash autovivification (facets) также может быть полезен.

1
ответ дан 28 November 2019 в 02:19
поделиться

Вы можете использовать Facets гем Hash.autonew , чтобы делать то же самое, что и рекурсивная функция, указанная в ответе Molf.

1
ответ дан 28 November 2019 в 02:19
поделиться

Использование символов, кажется, работает:

ree-1.8.7-2009.10 > @date = {:month =>{:day => {:hours => {:min => {:sec => 1 } } } } }
 => {:month=>{:day=>{:hours=>{:min=>{:sec=>1}}}}} 

Затем я могу получить val следующим образом:

ree-1.8.7-2009.10 > @date[:month][:day]
 => {:hours=>{:min=>{:sec=>1}}}
2
ответ дан 28 November 2019 в 02:19
поделиться