626 Stimmen

Wie summiert man ein Array von Zahlen in Ruby?

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.

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

862voto

jomey Punkte 8529

Für ruby >= 2.4 können Sie sum verwenden:

array.sum

Für ruby < 2.4 können Sie inject verwenden:

array.inject(0, :+)

Hinweis: Der 0 Basisfall ist erforderlich, da andernfalls nil bei leeren Arrays zurückgegeben wird:

> [].inject(:+)
nil
> [].inject(0, :+)
0

6 Stimmen

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?

1 Stimmen

Pablo: Du kannst machen: array.map{|p| p.price}.inject(+:)

7 Stimmen

Sie können einen ähnlichen Trick mit der map-Methode verwenden: array.map(&:price).inject(:+)

648voto

zenazn Punkte 14115

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)

327 Stimmen

Das array.inject(:+) von Jorney ist effizienter.

4 Stimmen

array.inject(:+) scheint in Ruby 1.8.6 Probleme zu verursachen. Es könnten Ausnahmen wie "LocalJumpError: es wurde kein Block angegeben" auftreten.

37 Stimmen

In Rails array.sum könnte Ihnen die Summe der Array-Werte geben.

305voto

Evan Punkte 7278
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:

12 Stimmen

Ich stimme zu, reduce sagt mir mehr darüber aus, was die Funktion tut, aber inject klingt viel cooler.

1 Stimmen

Stimme dem letzten Kommentar zu, du hast mir die beste Antwort gegeben.

1 Stimmen

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.

118voto

Mike Woodhouse Punkte 50241

Alternativ (nur zum Vergleich), wenn Sie Rails installiert haben (eigentlich nur ActiveSupport):

require 'activesupport'
array.sum

13 Stimmen

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

2 Stimmen

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.

1 Stimmen

Kleinkariertheit zu einem ansonsten guten Kommentar: Es sollte require 'active_support/core_ext/enumerable' ohne den .rb Suffix sein, da dieser implizit hinzugefügt wird.

97voto

jrhicks Punkte 14251

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

1 Stimmen

Bitte nicht machen

0 Stimmen

@user3467349 warum?

19 Stimmen

Das Ändern von Basisklassen ist nicht schön.

CodeJaeger.com

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.

Powered by:

X