Ik heb een array van gehele getallen.
Bijvoorbeeld:
array = [123,321,12389]
Is er een leuke manier om de som ervan te krijgen?
Ik weet het, dat
sum = 0
array.each { |a| sum+=a }
zou werken.
Antwoord 1, autoriteit 100%
Probeer dit:
array.inject(0){|sum,x| sum + x }
Zie Ruby’s opsombare documentatie
(opmerking: het basisgeval 0
is nodig zodat 0
wordt geretourneerd op een lege array in plaats van nil
)
Antwoord 2, autoriteit 99%
Of probeer de Ruby 1.9-manier:
array.inject(0, :+)
Opmerking: het basisgeval 0
is nodig, anders wordt nil
geretourneerd op lege arrays:
> [].inject(:+)
nil
> [].inject(0, :+)
0
Antwoord 3, autoriteit 48%
array.reduce(0, :+)
Hoewel equivalent aan array.inject(0, :+)
, begint de term reduceeen meer gebruikelijke volkstaal te worden met de opkomst van MapReduce-programmeermodellen.
Inject , verminderen , vouw , accumuleren , en comprimeren zijn allemaal synoniem als een klasse van vouwfuncties . Ik vind consistentie in uw codebasis het belangrijkste, maar aangezien verschillende gemeenschappen de voorkeur geven aan één woord over een ander, is het niettemin nuttig om de alternatieven te kennen.
Om de verbeage van de kaart te benadrukken, is hier een versie die een beetje meer vergevingsgezind is voor wat er in die array terechtkomt.
array.map(&:to_i).reduce(0, :+)
Enkele extra relevante informatie:
- http://ruby-doc.org/core-1.9.3 /Enumerable.html#Method-i-Inject
- http://en.wikipedia.org/wiki/mapreduce
- http://en.wikipedia.org/wiki/fold_(Higher-order_function)
Antwoord 4, Autoriteit 18%
Als alternatief (alleen voor vergelijking), als u rails hebt geïnstalleerd (eigenlijk gewoon ActiveSupport):
require 'activesupport'
array.sum
Antwoord 5, Autoriteit 14%
Voor Ruby & GT; = 2.4.0 U kunt sum
gebruiken vanuit de incommunautabelen.
[1, 2, 3, 4].sum
Het is gevaarlijk voor MokePatch-basisklassen. Als u van gevaar houdt en een oudere versie van Ruby gebruikt, kunt u #sum
toevoegen aan de Array
klasse:
class Array
def sum
inject(0) { |sum, x| sum + x }
end
end
Antwoord 6, autoriteit 8%
Nieuw voor Ruby 2.4.0
Je kunt de toepasselijk genaamde methode Enumerable#sum
gebruiken. Het heeft veel voordelen ten opzichte van inject(:+)
, maar er zijn ook enkele belangrijke opmerkingen aan het einde.
Voorbeelden
Bereiken
(1..100).sum
#=> 5050
Arrays
[1, 2, 4, 9, 2, 3].sum
#=> 21
[1.9, 6.3, 20.3, 49.2].sum
#=> 77.7
Belangrijke opmerking
Deze methode is niet gelijk aan #inject(:+)
. Bijvoorbeeld
%w(a b c).inject(:+)
#=> "abc"
%w(a b c).sum
#=> TypeError: String can't be coerced into Integer
Ook
(1..1000000000).sum
#=> 500000000500000000 (execution time: less than 1s)
(1..1000000000).inject(:+)
#=> 500000000500000000 (execution time: upwards of a minute)
Zie dit antwoordvoor meer informatie over waarom sum
zo is.
Antwoord 7, autoriteit 3%
Ruby 2.4+ / Rails – array.sum
d.w.z. [1, 2, 3].sum # => 6
Ruby pre 2.4 – array.inject(:+)
of array.reduce(:+)
*Opmerking: de methode #sum
is een nieuwe toevoeging aan 2.4 voor enumerable
, dus u kunt nu array.sum
gebruiken in pure robijn, niet alleen Rails.
Antwoord 8, autoriteit 3%
Voor de diversiteit kun je dit ook doen als je array geen array van getallen is, maar eerder een array van objecten met eigenschappen die getallen zijn (bijvoorbeeld hoeveelheid):
array.inject(0){|sum,x| sum + x.amount}
Antwoord 9, autoriteit 3%
robijn 1.8.7 manier is de volgende:
array.inject(0, &:+)
Antwoord 10
Ruby 2.4.0 is uitgebracht en heeft een Enumerable#summethode. Dus je kunt doen
array.sum
Voorbeelden uit de documenten:
{ 1 => 10, 2 => 20 }.sum {|k, v| k * v } #=> 50
(1..10).sum #=> 55
(1..10).sum {|v| v * 2 } #=> 110
Antwoord 11
voor array met nulwaarden kunnen we compact doen en vervolgens de som injecteren
ex-
a = [1,2,3,4,5,12,23.45,nil,23,nil]
puts a.compact.inject(:+)
Antwoord 12
Ook [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
Antwoord 13
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:
Wanneer Array nul en lege waarden bevat, zal standaard, als u een van de bovenstaande functies gebruikt, alles verminderen, optellen, injecteren via de
TypeError: nul kan niet worden afgedwongen tot Integer
Je kunt dit oplossen door,
[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
Evalueert de Ruby-expressie(s) in string.
[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+
Antwoord 14
Als u zich golfachtig voelt, kunt u dat doen
eval [123,321,12389]*?+
Hiermee wordt een tekenreeks “123+321+12389” gemaakt en vervolgens wordt de functie eval gebruikt om de som uit te voeren. Dit is alleen voor golfdoeleinden, u mag het niet in de juiste code gebruiken.
Antwoord 15
Je kunt het ook op een gemakkelijke manier doen
def sum(numbers)
return 0 if numbers.length < 1
result = 0
numbers.each { |num| result += num }
result
end
Antwoord 16
U kunt .mapen .sumgebruiken als:
array.map { |e| e }.sum