def merge_sum(*hashes)
total_hash = {}
hashes.each do |hash|
hash.each_pair do |key, value|
total_hash[key] ||= 0
total_hash[key] += value
end
end
total_hash
end
p merge_sum({'a'=>1, 'b'=>1}, {'b'=>1, 'c'=>1})
Поясните, пожалуйста, насчет конструкции '||='. Общий смысл понятен — 'если
такого колюча нет — инициализировать пару нулем', но хотелось бы почитать
документацию, чтобы понять, где еще это можно использовать.
Posted via RSDN NNTP Server 2.1 beta
Здравствуйте, DemAS, Вы писали:
DAS>DAS>def merge_sum(*hashes)
DAS> total_hash = {}
DAS> hashes.each do |hash|
DAS> hash.each_pair do |key, value|
DAS> total_hash[key] ||= 0
DAS> total_hash[key] += value
DAS> end
DAS> end
DAS> total_hash
DAS>end
DAS>p merge_sum({'a'=>1, 'b'=>1}, {'b'=>1, 'c'=>1})
DAS>
DAS>Поясните, пожалуйста, насчет конструкции '||='. Общий смысл понятен — 'если
DAS>такого колюча нет — инициализировать пару нулем', но хотелось бы почитать
DAS>документацию, чтобы понять, где еще это можно использовать.
a = 5 # обычное присвоение
a = a || 5 # || — это оператор «или»; если a == false или nil, то эта конструкция пишет 5 в a
a ||= 5 # краткая запись той же строки, как x +=1 — краткая запись выражения x = x + 1
total_hash[key] # выражение всегда возвращает значение из словаря;
# если значения с таким ключом в словаре нету, возвращает nil
# таким образом:
total_hash[key] ||= 0
# эквивалентно:
total_hash[key] = total_hash[key] || 0 # не изменяем значение, если оно уже есть, а если нет — записываем 0
Заметим в скобках, что этот пример — не очень хороший руби-код. Например, если читать документацию, можно написать хотя бы так:
def merge_sum(*hashes)
total_hash = Hash.new(0)
hashes.each do |hash|
hash.each_pair do |key, value|
total_hash[key] += value
end
end
total_hash
end
А можно — так:
def merge_sum(*hashes)
hashes.inject({}){|res, has|
res.merge(hash){|k, v1, v2| v1 + v2}
}
end
А можно — так:
class Hash
def merge_sum(*hashes)
hashes.inject(self){|res, has|
res.merge(hash){|k, v1, v2| v1 + v2}
}
end
end
p( {'a'=>1, 'b'=>1}.merge_sum('b'=>1, 'c'=>1) )
Programming Ruby можно за день пролистать, честное слово!