Ich habe ein Array von ganzen Zahlen.
Zum Beispiel:
array = [123,321,12389]
Gibt es einen einfachen Weg, um ihre Summe zu erhalten?
Ich weiß, dass
sum = 0
array.each { |a| sum+=a }
funktionieren würde.
Ich habe ein Array von ganzen Zahlen.
Zum Beispiel:
array = [123,321,12389]
Gibt es einen einfachen Weg, um ihre Summe zu erhalten?
Ich weiß, dass
sum = 0
array.each { |a| sum+=a }
funktionieren würde.
Wie kann ich diesen Weg benutzen, um ein Attribut von Objekt zu summieren? Mein Array [Produkt1, Produkt2] Ich möchte Produkt1.Preis + Produkt2.Preis summieren. Ist es möglich, array.inject(: +) zu verwenden?
Sie können einen ähnlichen Trick mit der map-Methode verwenden: array.map(&:price).inject(:+)
Versuche es damit:
array.inject(0){ |sum, x| sum + x }
Siehe Rubys Enumerable-Dokumentation
(Hinweis: Der 0
Basisfall ist erforderlich, damit 0
bei einem leeren Array zurückgegeben wird, anstatt nil
)
array.inject(:+)
scheint in Ruby 1.8.6 Probleme zu verursachen. Es könnten Ausnahmen wie "LocalJumpError: es wurde kein Block angegeben" auftreten.
array.reduce(0, :+)
Obwohl äquivalent zu array.inject(0, :+)
ist, wird der Begriff reduce mit dem Aufkommen von MapReduce-Programmiermodellen in eine häufigere Umgangssprache übergehen.
inject, reduce, fold, accumulate und compress sind alle synonym als Klasse von Faltungsfunktionen. Ich finde Konsistenz in Ihrem Code-Bestand am wichtigsten, aber da verschiedene Gemeinschaften tendenziell ein Wort gegenüber einem anderen bevorzugen, ist es dennoch nützlich, die Alternativen zu kennen.
Um die Map-Reduce-Sprache zu betonen, hier ist eine Version, die etwas toleranter ist, was in diesem Array landet.
array.map(&:to_i).reduce(0, :+)
Einige zusätzliche relevante Lektüre:
Ich stimme zu, reduce
sagt mir mehr darüber aus, was die Funktion tut, aber inject
klingt viel cooler.
Der einzige Kommentar, den ich machen würde, ist, dass reduce
und map
als Funktionen höherer Ordnung MapReduce vorausgehen. Die Inspiration verläuft umgekehrt. Und im Sinne von MapReduce handelt es sich um eine etwas andere Operation als eine einfache funktionale Reduzierung, die Auswirkungen darauf hat, wie verschiedene Maschinen kommunizieren.
Neuere Versionen von activesupport laden standardmäßig nicht alle Erweiterungen tatsächlich. Sie möchten entweder nur das Summenmodul erfordern: require 'active_support/core_ext/enumerable.rb'
, oder alle von Active Support fordern: require 'active_support/all'
. Weitere Informationen dazu hier: API-Dokumente
Ganz gleich, dass activesupport
eine massive Abhängigkeit ist, die in ein Projekt gezogen werden muss, um von array.inject(:+)
auf array.sum
zu wechseln.
Für Ruby >=2.4.0 können Sie sum
von Enumerables verwenden.
[1, 2, 3, 4].sum
Es ist gefährlich, Basisklassen zu monkeypatchen. Wenn Sie gerne Risiken eingehen und eine ältere Version von Ruby verwenden, könnten Sie #sum
zur Klasse Array
hinzufügen:
class Array
def sum
inject(0) { |sum, x| sum + x }
end
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
40 Stimmen
Bitte beachten Sie, dass Ruby 2.4+
array.sum
hat.1 Stimmen
Ruby 2.6 hat es nicht. Ruby gibt, Ruby nimmt anscheinend weg.
2 Stimmen
@Lori hmm ? Verknüpfung
2 Stimmen
Entschuldigung. Zu der Zeit glaubte ich irrtümlicherweise, dass ich Version 2.6 verwendete, aufgrund eines Fehlers von meiner Seite mit rbenv.
0 Stimmen
Wenn Sie einen Standardwert angeben müssen, wenn das
Array
leer ist, z. B. wenn Sie einMoney
-Objekt anstelle einerInteger
zurückgeben möchten, können Sie etwas Ähnliches wiearray.sum( 0.to_money( "USD" ) )
tun.