Ruby hash эквивалент Python dict setdefault

В Python можно читать словарь / хеш-ключ, в то же время устанавливая ключ по умолчанию, если он еще не существует.

Например:

>>> d={'key': 'value'} >>> d.setdefault('key', 'default') 'value' # returns the existing value >>> d.setdefault('key-doesnt-exist', 'default') 'default' # sets and returns default value >>> d {'key-doesnt-exist': 'default', 'key': 'value'} 

Есть ли эквивалент с хэшами Ruby? Если нет, то каков идиоматический подход в Ruby?

4 Solutions collect form web for “Ruby hash эквивалент Python dict setdefault”

Хэш может иметь значение по умолчанию или по умолчанию Proc (который вызывается, когда ключ отсутствует).

 h = Hash.new("hi") puts h[123] #=> hi # change the default: h.default = "ho" 

В приведенном выше случае хэш остается пустым.

 h = Hash.new{|h,k| h[k] = []} h[123] << "a" ph # =>{123=>["a"]} 

Hash.new([]) не работал бы, потому что для каждого ключа использовался бы тот же массив (тот же, что и у идентичного объекта).

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

В то же время мы в настоящее время просто делаем то, что setDefault делает следующее:

 h = {} h['key'] ||= 'value' 

Рубин продолжал двигаться домой:

 h.default = "Hey now" h.fetch('key', 'default') # => 'value' h.fetch('key-doesnt-exist', 'default') # => 'default' # h => {'key' => 'value'} h['not your key'] # => 'Hey now' 

Python:

 h = {'key':'value'} h.setdefault('key','default') # => 'value' h.setdefault('key-doesnt-exist','default') # => 'default' # h {'key': 'value', 'key-doesnt-exist': 'default'} h['not your key'] # => KeyError: 'not your key' 

Вы можете просто передать блок конструктору Hash :

 hash = Hash.new do |hash, key| hash[key] = :default end 

Блок будет вызываться при попытке получить доступ к несуществующему ключу. Он будет передан хэш-объект и ключ. Вы можете делать с ними все, что хотите; установите ключ в значение по умолчанию, выведите новое значение из ключа и т. д.

Если у вас уже есть объект Hash , вы можете использовать метод default_proc= :

 hash = { key: 'value' } # ... hash.default_proc = proc do |hash, key| hash[key] = :default end 

В Python нет эквивалента этой функции. Вы можете всегда использовать патч обезьяны, чтобы получить эту функциональность:

 class Hash def setdefault(key, value) if self[key].nil? self[key] = value else self[key] end end end h = Hash.new h = { 'key' => 'value' } h.setdefault('key', 'default') # => 'value' h.setdefault('key-doesnt-exist', 'default') # => 'default' 

Но имейте в виду, что исправление обезьян часто рассматривается как табу, по крайней мере, в определенных средах кода.

Золотое правило патчей обезьян применяется: только потому, что вы могли, не означает, что вы должны.

Более идиоматичным способом является определение значений по умолчанию через конструктор Hash путем передачи дополнительного блока или значения.

Python - лучший язык программирования в мире.