2017-07-04 1 views
0

Ich habe eine Klasse namens Food; Es ist eine sehr einfache Klasse, es hat nur Namen, Preis und Kcal. Ich habe drei Arten von Food:Verwenden Sie reduzieren, um Attribute von Objekten im Array zu summieren

@Menu = [@Food1, @Food2, @Food3] 

Ich brauche alle zu summieren die prices mit dem reduce Methode, und speichern sie in @Food1:

@Food1 = Food.new("Pear", 12, 120) 
@Food2 = Food.new("Apple", 15, 100) 
@Food3 = Food.new("Banana", 20, 200) 

Dann habe ich eine Reihe von Lebensmitteln Menu genannt erstellt. Ich habe die + Methode zur food Klasse implementiert:

def + (other) 
    @price + other.price 
end 

Und ich versuche zu tun:

@Food1 = @Menu.reduce(:+) 

Aber es funktioniert nicht. Hast du eine Idee, wie ich das erreichen kann?

+2

Die Ruby-Konvention besagt, dass Variablen und Methodennamen nur Kleinbuchstaben enthalten dürfen. Das ist '@ food1' und' @ menu' in diesem Fall. – tadman

+0

Was bedeutet "nicht funktioniert"? Gibt es einen Fehler? – tadman

+0

Zeigen Sie andere relevante Teile von Ihnen Code. Ohne die Initialisierungsmethode zu definieren, funktioniert Ihr Code nicht.Ohne eine Accessor-Methode funktioniert Ihr Code nicht. – sawa

Antwort

3

Der einfachste Weg ist, es wie folgt zu schreiben.

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

food1 = Food.new("Pear", 12, 120) 
food2 = Food.new("Apple", 15, 100) 
food3 = Food.new("Banana", 20, 200) 
menu = [food1, food2, food3]`enter code here` 

menu.reduce(0) { |t,food| t+food.price } 
    #=> 47 

oder (für + Rubin v2.4)

menu.sum { |food| food.price } 

bemerken, dass ich nicht food1 definiert haben, food2, food3 oder menu als Instanzvariablen. Es mag einen Grund dafür geben, aber nicht nur, um die Summe der Preise zu erhalten.

ist eine ganze Zahl, für die Integer#+ natürlich definiert ist, so gibt es keinen besonderen Grund zu definieren und Instanz Methode + auf der Klasse.

Angenommen, Sie eine Instanz Methode :+ zur Klasse hinzugefügt haben:

def +(other) 
    price + other.price 
end 

Diese Sie

food1 + food2 
    #=> 27 

zu schreiben erlauben würde (auch wenn es nicht intuitiv ist, dass die Preise summiert werden). Sie können jedoch nicht

food1 + food2 + food3 

schreiben, weil food1 + food2 zuerst ausgeführt wird, Rückkehr 27, dann wird ein Versuch

27 + food3 

auszuführen gemacht, die für

27.+(food3) 

Hier :+ syntaktischer Zucker ist eine Integer-Methode, die food3 nicht als Argument akzeptiert und daher eine Ex-Zahl erstellt Aufnahme.

+1

... deshalb sollten Sie 'coerce' immer implementieren, wenn Sie möchten, dass sich Ihre Objekte wie Zahlen verhalten. –

Verwandte Themen