[ruby] ||=
От: DemAS http://demas.me
Дата: 11.07.09 19:38
Оценка:
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
Re: [ruby] ||=
От: Гест Украина https://zverok.github.io
Дата: 11.07.09 20:04
Оценка: 7 (2) +1
Здравствуйте, 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 можно за день пролистать, честное слово!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.