Установка рубина хеширует .default к списку [дубликат]

40
задан Martin Konecny 27 January 2016 в 17:10
поделиться

6 ответов

Hash.default используется для установки значения по умолчанию , возвратился , когда Вы запрашиваете ключ, который не существует. Запись в наборе не создается для Вас, просто потому что запрошенный это.

кроме того, значение Вы устанавливаете default на, экземпляр объекта (Массив в Вашем случае), поэтому когда это возвращается, этим можно управлять.

a = {}
a.default = []     # set default to a new empty Array
a[8] << 9          # a[8] doesn't exist, so the Array instance is returned, and 9 appended to it
a.default          # => [9]
a[9]               # a[9] doesn't exist, so default is returned
49
ответ дан Aaron Hinni 27 November 2019 в 01:02
поделиться

Это - очень полезная идиома:

(myhash[key] ||= []) << value

Это может даже быть вложено:

((myhash[key1] ||= {})[key2] ||= []) << value

другой путь состоит в том, чтобы сделать:

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

, Но это имеет значительный побочный эффект, что выяснение о ключе создаст его, который представляет has_key? довольно бесполезный, таким образом, я избегаю этого метода.

52
ответ дан glenn mcdonald 27 November 2019 в 01:02
поделиться

Я думаю, что это - поведение, которое Вы ищете. Это автоматически инициализирует любые новые ключи в Хеше к массиву:

irb(main):001:0> h = Hash.new{|h, k| h[k] = []}
=> {}
irb(main):002:0> h[1] << "ABC"
=> ["ABC"]
irb(main):003:0> h[3]
=> []
irb(main):004:0> h
=> {1=>["ABC"], 3=>[]}
33
ответ дан Turp 27 November 2019 в 01:02
поделиться
irb(main):002:0> a.default = []
=> []
irb(main):003:0> a[8] << 9
=> [9]                          # great!

С этим оператором, Вы изменили значение по умолчанию; Вы не создали новый массив и добавили "9". На данном этапе это идентично тому, если Вы сделали это вместо этого:

irb(main):002:0> a.default = [9]
=> [9]

Следовательно не удивительно, что Вы теперь получаете это:

irb(main):006:0> a[9]
=> [9]                          # unawesome! shouldn't this be [] ??

, Кроме того, '< <'; добавленный '9' к массиву; это не добавило его к хешу, который объясняет это:

irb(main):004:0> a
=> {}                           # ?! would have expected {8=>[9]}

Вместо того, чтобы использовать .default, что Вы, вероятно, хотите сделать в своей программе, что-то вроде этого:

# Time to add a new entry to the hash table; this might be 
# the first entry for this key..
myhash[key] ||= []
myhash[key] << value
6
ответ дан Simon Howard 27 November 2019 в 01:02
поделиться

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

h = Hash.new { [] }
h[:missing]
   => []

#But, you should never modify the empty array because it isn't stored anywhere
#A new, empty array is returned every time
h[:missing] << 'entry'
h[:missing]
   => []
-4
ответ дан Daniel Beardsley 27 November 2019 в 01:02
поделиться

Гленн Макдональд говорит:

«Другой способ - сделать:

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

Но у этого есть существенный побочный эффект: вопрос о ключе создаст его, что делает has_key? Довольно бесполезным, поэтому я избегаю этого метода »

, который на самом деле не кажется правда.

irb(main):004:0> a = Hash.new {|hash,key| hash[key] = []}
=> {}
irb(main):005:0> a.has_key?(:key)
=> false
irb(main):006:0> a[:key]
=> []
irb(main):007:0> a.has_key?(:key)
=> true

Доступ к ключ создаст его, как я и ожидал. Просто спросите has_key? не.

9
ответ дан 27 November 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: