2013-03-07 12 views
12

Ho un modello venditore che ha_molti articoli.Trattando nil come funzione di somma pari a zero

Desidero ottenere il prezzo di vendita totale di tutti gli articoli di un venditore.

In seller.rb devo

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

Questo funziona bene se tutti gli elementi hanno un prezzo di vendita.
Tuttavia, se non sono ancora stati venduti, sale_price è nullo e le interruzioni total_item_cost.

Nella mia app, sale_price può essere un numero zero o uno zero.

Nel mio metodo total_item_cost, come posso considerare i valori nil come zero?

+0

Non sarebbe meglio definire SALE_PRICE come metodo e farla tornare sempre 0? Sarebbe la mia preferenza personale, perché conserva tutta la conoscenza del sale_price a cui appartiene, in modo da diffondersi su tutta la domanda sotto forma di "se sale_price.nil?". – berkes

+0

In realtà è un'asta - un oggetto può essere "venduto" per 0 (il che significa che nessuno lo voleva). Quindi zero significa che non è stato ancora messo all'asta, e zero significa che è passato. Ho altre definizioni per tenere traccia di questo. –

risposta

30

Un modo è:

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

Metodi come #to_f e #to_i si trasformerà in nil0.

+0

Perfetto, grazie. –

+0

Sfortunatamente ".to_d" (decimale) non funziona con nils e arresti anomali. I costi per i prezzi possono portare a calcoli matematici imprecisi. Ho finito per mettere le colonne che avevo bisogno di sommare in un array, poi compatto (per rimuovere nils) quindi sum, simile alla risposta di @ dbenhur. – JosephK

1

Rifiuta i valori nulli. items.to_a.reject{|x| x.sales_price.nil?}.sum(&:sale_price)

+2

['Array # compact'] (http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-compact) è un modo più conciso per rifiutare i nils. – dbenhur

35
items.map(&:sale_price).compact.sum 

o

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

Questa dovrebbe essere la risposta accettata. –

+0

Il vincitore !! ;) – Mauro

Problemi correlati