2016-06-05 3 views
0

Ich habe folgende hash:`inject` Mit` Wert * qty` in einem Hash hinzuzufügen

{#<Dish:0x007fb45505ff30 @dish={:name=>"Chicken Pie", :price=>4.5}> => 2} 

Um die price * qty (die 2 am Ende ist) zu addieren, ich bin mit der Code:

@order.map { |item, qty| item.price * qty }.inject(:+) 

die einen Wert von 9 zurückgibt.

Gibt es trotzdem, diesen Code zu etwas entlang der Linie der neu zu schreiben:

@order.inject(0) { |item, qty| item.price * qty } 
+0

Was ist '@ bestellen'? – sawa

+1

Seien Sie vorsichtig bei der Verwendung Ihres benutzerdefinierten Objekts als Hash-Schlüssel. Hast du einen Hash und == oder eql implementiert? Methode? –

+0

Wenn Sie Rails verwenden, können Sie 'sum' wie '@order.sum {| item, qty | verwenden item.price * qty} ' – potashin

Antwort

2

Hier ist ein Beispiel:

class Item 
    attr_reader :name, :price 
    def initialize(name, price) 
    @name = name 
    @price = price 
    end 
end 

data = {Item.new('Book', 10) => 2, Item.new('Sandwich', 33) => 1} 
sum = data.inject(0) do |total, (item, amount)| 
    total + item.price * amount 
end 

puts "Total: #{sum}" 

berücksichtigt Kommentar von Keith: benutzerdefinierte Objekte als Hash-Schlüssel funktioniert möglicherweise nicht wie erwartet, es sei denn, Sie haben sich um die Identität gekümmert.

1
@order.inject(0){|n, (item, qty)| n + item.price * qty} 
0

Was möchten Sie tun, wenn es mehr als ein Gericht in diesem Hash gibt? Was ist das tatsächliche Verhalten, das du willst?

Wenn Sie nur den Gesamtpreis eines einzelnen Item-Hashes kennen und Ihr inject-Beispiel verwenden möchten, müssen Sie sich daran erinnern, dass Sie versuchen, einen Hash zu injizieren, der Memo- und Elementblockargumente benötigt - und in Ihrem Fall Das Element wird das Schlüsselwertpaar jedes Elements in Ihrem Hash sein.

Zum Beispiel:

@order.inject(0) { |item, qty| puts item.inspect } 

und sehen, was Sie erhalten. Etwas in der Richtung von [#<Dish:0x007fb45505ff30 @dish={:name=>"Chicken Pie", :price=>4.5}>, 2] ich denke.

So erfassen Sie das Array von Schlüsselwert in zwei anderen Argumenten.

@order.inject(0) { |memo, (item, qty)| memo + (item.price * qty) } 
Verwandte Themen