26 votes

Traitement de nil comme zéro dans la fonction somme

J'ai un modèle de vendeur qui possède plusieurs articles.

Je veux obtenir le prix de vente total de tous les articles d'un vendeur.

Dans seller.rb j'ai

def total_item_cost 
  items.to_a.sum(&:sale_price)
end

Cela fonctionne bien si tous les éléments ont un prix de vente.
Cependant, s'ils n'ont pas encore été vendus, sale_price est nul et le total_item_cost pauses.

Dans mon application, sale_price peut être soit un zéro, soit un zéro.

Dans mon total_item_cost méthode, comment puis-je traiter nil comme des zéros ?

0 votes

Ne serait-il pas préférable de définir sale_price comme une méthode et de faire en sorte qu'elle renvoie toujours 0 ? C'est ce que je préfère personnellement, car cela permet de conserver toutes les connaissances sur le prix de vente là où elles doivent être, au lieu de les disperser dans toute l'application sous la forme de if sale_price.nil? .

0 votes

Il s'agit en fait d'une vente aux enchères : un objet peut être "vendu" pour 0 (ce qui signifie que personne n'en veut). Donc nil signifie qu'il n'a pas encore été mis aux enchères, et zéro signifie qu'il a été adjugé. J'ai d'autres définitions pour garder une trace de tout cela.

64voto

dbenhur Points 9694
items.map(&:sale_price).compact.sum

ou

items.map(&:sale_price).sum(&:to_i)

41voto

DigitalRoss Points 80400

Une façon de le faire :

items.to_a.sum { |e| e.sale_price.to_i } # or to_f, whatever you are using

Des méthodes comme #to_f y #to_i tournera nil en 0 .

1 votes

Malheureusement, ".to_d" (décimal) ne fonctionne pas avec les nils et plante. Les valeurs flottantes pour les prix peuvent conduire à des calculs imprécis. J'ai fini par mettre les colonnes dont j'avais besoin pour faire la somme dans un tableau, puis j'ai compacté (pour supprimer les nils), puis j'ai fait la somme, comme dans la réponse de @dbenhur.

3voto

benchwarmer Points 2724

Rejeter les valeurs nulles. items.to_a.reject{|x| x.sales_price.nil?}.sum(&:sale_price)

4 votes

Array#compact est une façon plus concise de rejeter les nils.

0voto

Chris Habgood Points 171

En supposant que sales_price est une colonne dans la BD :

items.sum(:sales_price)

0voto

januszm Points 305
# Ruby 2.7+
items.filter_map(&:sale_price).sum

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X