it-swarm.com.de

Wie man ein Array von Zahlen in Ruby summiert?

Ich habe eine Reihe von ganzen Zahlen.

Zum Beispiel:

array = [123,321,12389]

Gibt es eine nette Möglichkeit, die Summe von ihnen zu erhalten?

Ich weiß das

sum = 0
array.each { |a| sum+=a }

würde funktionieren.

549
brainfck

Versuche dies:

array.inject(0){|sum,x| sum + x }

Siehe Ruby's Enumerable Documentation

(Hinweis: Der Basisfall 0 wird benötigt, damit 0 in einem leeren Array anstelle von nil zurückgegeben wird.)

597
zenazn

Oder probieren Sie den Ruby 1.9-Weg:

array.inject(0, :+)

Hinweis: Der Grundfall 0 wird benötigt, andernfalls nil wird auf leeren Arrays zurückgegeben:

> [].inject(:+)
nil
> [].inject(0, :+)
0
794
jomey
array.reduce(0, :+)

Während array.inject(0, :+) entspricht, wird der Begriff redu mit dem Aufkommen von MapReduce-Programmiermodellen allgemeiner .

injizieren , reduzieren , falten , akkumulieren und komprimieren sind alle auch eine klasse von faltfunktionen . Ich finde die Konsistenz in Ihrer Codebasis am wichtigsten, aber da verschiedene Communities dazu neigen, ein Wort einem anderen vorzuziehen, ist es dennoch nützlich, die Alternativen zu kennen.

Um die kartenreduzierte Ausdrucksweise hervorzuheben, finden Sie hier eine Version, die etwas mehr darüber nachdenkt, was in diesem Array landet.

array.map(&:to_i).reduce(0, :+)

Einige zusätzliche relevante Lektüre:

278
Evan

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

require 'activesupport'
array.sum
110
Mike Woodhouse

Für Ruby> = 2.4.0 können Sie sum aus Enumerables verwenden.

[1, 2, 3, 4].sum

Es ist gefährlich, Basisklassen zu mokeypatchen. Wenn Sie Gefahr mögen und eine ältere Version von Ruby verwenden, können Sie #sum zur Klasse Array hinzufügen:

class Array
  def sum
    inject(0) { |sum, x| sum + x }
  end
end
58
jrhicks

Neu für Ruby 2.4.0

Sie können die treffend benannte Methode Enumerable#sum verwenden. Es hat viele Vorteile gegenüber inject(:+), aber es gibt auch einige wichtige Hinweise, die Sie am Ende lesen sollten.

Beispiele

Bereiche

(1..100).sum
#=> 5050

Arrays

[1, 2, 4, 9, 2, 3].sum
#=> 21

[1.9, 6.3, 20.3, 49.2].sum
#=> 77.7

Wichtige Notiz

Diese Methode entspricht nicht #inject(:+). Zum Beispiel

%w(a b c).inject(:+)
#=> "abc"
%w(a b c).sum
#=> TypeError: String can't be coerced into Integer

Ebenfalls,

(1..1000000000).sum
#=> 500000000500000000 (execution time: less than 1s)
(1..1000000000).inject(:+)
#=> 500000000500000000 (execution time: upwards of a minute)

Siehe diese Antwort für weitere Informationen darüber, warum sum so ist.

40
Eli Sadoff

Ruby 2.4+/Rails - array.sum, d. H. [1, 2, 3].sum # => 6

Ruby vor 2.4 - array.inject(:+) oder array.reduce(:+)

* Hinweis: Die #sum -Methode ist eine neue Ergänzung zu 2.4 für enumerable, sodass Sie jetzt array.sum in reinem Ruby verwenden können, nicht nur in Rails.

19
collect

Nur aus Gründen der Vielfalt können Sie dies auch tun, wenn es sich bei Ihrem Array nicht um ein Array von Zahlen handelt, sondern um ein Array von Objekten, deren Eigenschaften Zahlen sind (z. B. Betrag):

array.inject(0){|sum,x| sum + x.amount}
19
HashFail

Ruby 1.8.7 Weg ist der folgende:

array.inject(0, &:+) 
18
Vova

Sie können einfach verwenden:

    example = [1,2,3]
    example.inject(:+)
16
Ganesh Sagare

Das ist genug [1,2,3].inject('+')

5
Mahesh Bablu

Ruby 2.4.0 wird veröffentlicht und enthält die Methode Enumerable # sum . Also kannst du es tun

array.sum

Beispiele aus den Dokumenten:

{ 1 => 10, 2 => 20 }.sum {|k, v| k * v }  #=> 50
(1..10).sum                               #=> 55
(1..10).sum {|v| v * 2 }                  #=> 110
4
Santhosh

Ermöglicht auch [1,2].sum{|x| x * 2 } == 6:

# http://madeofcode.com/posts/74-Ruby-core-extension-array-sum
class Array
  def sum(method = nil, &block)
    if block_given?
      raise ArgumentError, "You cannot pass a block and a method!" if method
      inject(0) { |sum, i| sum + yield(i) }
    elsif method
      inject(0) { |sum, i| sum + i.send(method) }
    else
      inject(0) { |sum, i| sum + i }
    end
  end
end
3
grosser

für ein Array mit Nullwerten können wir kompakt machen und dann die Summe

a = [1,2,3,4,5,12,23.45,nil,23,nil]
puts a.compact.inject(:+)
3
pawan
array.reduce(:+)

Funktioniert auch für Ranges ... daher

(1..10).reduce(:+) returns 55
2
MulleOne

Methode 1:

    [1] pry(main)> [1,2,3,4].sum
    => 10
    [2] pry(main)> [].sum
    => 0
    [3] pry(main)> [1,2,3,5,nil].sum
    TypeError: nil can't be coerced into Integer

Methode 2:

   [24] pry(main)> [].inject(:+)
   => nil
   [25] pry(main)> [].inject(0, :+)
   => 0
   [4] pry(main)> [1,2,3,4,5].inject(0, :+)
   => 15
   [5] pry(main)> [1,2,3,4,nil].inject(0, :+)
   TypeError: nil can't be coerced into Integer
   from (pry):5:in `+'

Methode 3:

   [6] pry(main)> [1,2,3].reduce(:+)
   => 6
   [9] pry(main)> [].reduce(:+)
   => nil
   [7] pry(main)> [1,2,nil].reduce(:+)
   TypeError: nil can't be coerced into Integer
   from (pry):7:in `+'

Methode 4: Wenn das Array null und leere Werte enthält, reduzieren, summieren und injizieren Sie bei Verwendung der oben genannten Funktionen standardmäßig alle Werte

TypeError: nil kann nicht in Integer umgewandelt werden

Sie können dies überwinden, indem Sie

   [16] pry(main)> sum = 0 
   => 0
   [17] pry(main)> [1,2,3,4,nil, ''].each{|a| sum+= a.to_i }
   => [1, 2, 3, 4, nil, ""]
   [18] pry(main)> sum
   => 10

Methode 6:eval

Wertet die Ruby Ausdrücke in Zeichenfolge aus.

  [26] pry(main)> a = [1,3,4,5]
  => [1, 3, 4, 5]
  [27] pry(main)> eval a.join '+'
  => 13
  [30] pry(main)> a = [1,3,4,5, nil]
  => [1, 3, 4, 5, nil]
  [31] pry(main)> eval a.join '+'
  SyntaxError: (eval):1: syntax error, unexpected end-of-input
  1+3+4+5+
1
Nataraja B

Wenn Sie sich golfen fühlen, können Sie es tun

eval([123,321,12389]*?+)

Dadurch wird eine Zeichenfolge "123 + 321 + 12389" erstellt und anschließend mit der Funktion eval die Summe berechnet. Das ist nur zum Golfen, du solltest es nicht im richtigen Code benutzen.

1
Ulysse BN

Oder Sie können diese Methode ausprobieren:

def sum arr
  0 if arr.empty
  arr.inject :+
end
0
ramin
number = [1..100]

number. each do |n|

    final_number = n.sum

    puts "The sum is #{final_number}"
end

* Das hat für mich als neuen Entwickler gut funktioniert. Sie können Ihren Nummernkreis anpassen, indem Sie die Werte in [] ändern.

0
Madeline Young

Dies ist der kürzeste Weg. Versuch es.

array.inject :+

0
Tej Poudel