我有这个Ruby地图:
FIXED_COUNTRY_TO_PHONE = {
'FI' => '+358501111',
'RU' => '4019900780',
'SE' => '+4672345678',
'UA' => '0123456789',
'KZ' => '0123456789'
}.freeze
如果其他值不匹配,如何设置最终值,例如'*' => '1234567'
?
答案 0 :(得分:4)
FIXED_COUNTRY_TO_PHONE = Hash.new('1234567').merge({
'FI' => '+358501111',
'RU' => '4019900780',
'SE' => '+4672345678',
'UA' => '0123456789',
'KZ' => '0123456789'
}).freeze
但简单
DEFAULT = "1234567".freeze
FIXED_COUNTRY_TO_PHONE["FI"] || DEFAULT
#=> "+358501111"
FIXED_COUNTRY_TO_PHONE["??"] || DEFAULT
#=> "1234567"
看起来也不错
答案 1 :(得分:4)
您可以使用Hash#default=
设置默认值:
hash = {
'FI' => '+358501111',
'RU' => '4019900780',
'SE' => '+4672345678',
'UA' => '0123456789',
'KZ' => '0123456789'
}
hash.default = '1234567'
hash['UK']
#=> '1234567'
答案 2 :(得分:3)
There are two main ways of dealing with this problem. @llya assigns a default value to the hash, @fl00r applies the default when the hash is evaluated for a non-existing key, causing nil
to be returned.
llya shows one way of implementing the default value. It is very clear but uses a few lines of code. Two other ways of doing that deserve mention (though I am not suggesting they are in any sense better than how llya has done it).
Set the default then add the key-value pairs:
hash = Hash.new('1234567').
merge('FI'=>'+358501111', 'RU'=>'4019900780', 'SE'=>'+4672345678',
'UA'=>'0123456789', 'KZ'=>'0123456789').
freeze
hash['oh, my']
#=> "1234567"
Use Object#tap
hash = { 'FI'=>'+358501111', 'RU'=>'4019900780', 'SE'=>'+4672345678',
'UA'=>'0123456789', 'KZ'=>'0123456789'
}.tap { |h| h.default = '1234567' }.
freeze
hash['oh, my']
#=> "1234567"
A variantof fl00r
's || DEFALULT
approach, which arguably reads better, is to use Hash#fetch:
hash = { 'FI'=>'+358501111', 'RU'=>'4019900780', 'SE'=>'+4672345678',
'UA'=>'0123456789', 'KZ'=>'0123456789' }
DEFAULT = "1234567"
hash.fetch('oh, my', DEFAULT)
#=> "1234567"
hash[key] || DEFAULT
clearly cannot be used if hash
has a key whose value may be nil
or false
, though that is not an issue here.
Both approaches have pros and cons. Setting a default value avoids the need for the retrieval of values (which may be done in multiple places) to be concerned about whether the hash contains a particular key, but on the other hand readers of those parts of the code may not be aware (or have forgotten) that the hash was defined with a default value. If the || DEFAULT
approach is used there is the possibility that the coder may forget to include || DEFAULT
in one or more places where the hash is referenced. In terms of code maintenance I would think it's a toss-up, provided the constant DEFAULT
is defined in close proximity to the hash, and commented suitably.
It seems to me that it's generally best to use a default value, and wherever the hash is referenced remind readers that it has a default value, either with a comment or a suggestive name for the hash (e.g., applies_to_oranges_with_default
).