Como você concisa obter o preço médio casa de um conjunto de casas?
Pergunta
Assumindo que a matriz @houses está configurado como se segue:
house1.price = 10
house2.price = 20
house3.price = 30
@houses << house1
@houses << house2
@houses << house3
Este é o ponto de nosso cálculo começando e queremos encontrar o preço médio de uma casa:
total = 0
average = 0
for h in @houses
total += h.price
end
average = total/@houses.size
Este parece ser um monte de digitação apenas para obter uma média.
Existe uma maneira melhor?
Solução
Use o href="http://www.ruby-doc.org/core/classes/Enumerable.html#M003129" rel="nofollow noreferrer"> inject
método em uma coleção de enumerable. Inject permite passar em um valor inicial para um 'acumulador' (0, neste caso), em seguida, aplicar uma operação a cada elemento na lista, e retornar um novo valor para o acumulador a serem passados ??para a próxima iteração.
O valor final do acumulador é então retornado da chamada inject
.
Portanto, neste caso, nós apenas somar todos os preços da habitação para o acumulador, então, finalmente, dividir pelo número total.
Você pode obter funkier e, provavelmente, comprimi-lo para baixo mais com algum rubi Skillz, mas isso é razoavelmente compreensível, e somente itera através da lista uma vez para somar os valores.
@houses.inject(0){|total, house| total + house.price} / @houses.size
Outras dicas
A resposta de Madlep funcionará em qualquer versão do Ruby a partir dos últimos anos. Mas se você está usando o Ruby 1.8.7 ou posterior, você pode expressá-la um pouco mais concisa como @houses.collect(&:price).inject(:+)/@houses.size
.
Aliás, eu tinha assumido essa técnica seria mais lento uma vez que tem para fazer um loop duas vezes, mas graças a otimizações no próprio Ruby, é realmente muito mais rápido até um par milhões de itens em meus testes sobre Ruby 1.8.7, e mais rápido ( mas não tanto), mesmo passado 10 milhões de itens em ruby ??1.9. Vai lhe mostrar a importância da criação de perfil.
Se você estiver em uma aplicação Rails, você pode fazer array.sum / array.size