Enumerable#sum

Added in v2.4 · Updated March 31, 2026 · Enumerable
ruby enumerable sum addition stdlib

The sum method adds together all elements in a collection. It is part of the Enumerable module, available on arrays, ranges, hashes, and any object that includes Enumerable. Ruby introduced this method in version 2.4 to provide a simpler, more readable alternative to reduce(:+) for common summation tasks.

[1, 2, 3, 4, 5].sum
# => 15

(1..5).sum
# => 15

Syntax

collection.sum
collection.sum(initial)
collection.sum { |element| block }
collection.sum(initial) { |element| block }

Parameters

ParameterTypeDefaultDescription
initialObject0Starting value added to the sum. For numbers this defaults to zero.
blockBlockNoneOptional block to transform each element before summing.

Basic Usage

Summing Numbers

The most common use case is adding up numbers:

prices = [29.99, 14.99, 9.99, 49.99]
prices.sum
# => 104.96

# Sum of a range
(1..100).sum
# => 5050

With Initial Value

Pass an initial value to start the sum from a different number:

[1, 2, 3].sum(10)
# => 16

# Useful for accumulating across multiple collections
total = [1, 2, 3].sum
total += [4, 5, 6].sum
total += [7, 8, 9].sum
# => 45

Empty Collections

For an empty collection, sum returns the initial value (zero by default):

[].sum
# => 0

[].sum(100)
# => 100

Using a Block

Pass a block to transform elements before summing:

# Square each number before summing
(1..4).sum { |i| i * i }
# => 30 (1 + 4 + 9 + 16)

# Sum only even numbers
(1..10).sum { |n| n.even? ? n : 0 }
# => 30 (2 + 4 + 6 + 8 + 10)

# Initial value with block
(1..4).sum(100) { |i| i * i }
# => 130 (100 + 1 + 4 + 9 + 16)

Block Semantics with Initial Value

When using both an initial value and a block, the initial value is added once at the end, not used as the starting accumulator:

[1, 2, 3].sum(10) { |n| n * 2 }
# => 10 + (1*2 + 2*2 + 3*2) = 10 + 12 = 22

With Hashes

scores = { alice: 85, bob: 92, carol: 78 }

# Sum values
scores.sum { |_name, score| score }
# => 255

# Sum with transformation
scores.sum(0) { |name, score| name.to_s.length + score }
# => 266 (length of :alice (5) + 85 + length of :bob (3) + 92 + length of :carol (5) + 78)

With Strings

# Concatenate strings
["hello", "world"].sum("")
# => "helloworld"

# With initial string
["a", "b", "c"].sum("prefix-")
# => "prefix-abc"

# With block - take first character of each
["cat", "dog", "bird"].sum("") { |word| word[0].to_s }
# => "cdb"

Difference from inject/reduce

sum is specialized for addition, making it more readable than reduce for simple summation:

# Using reduce
[1, 2, 3].reduce(0, :+)
# => 6

# Using sum (cleaner)
[1, 2, 3].sum
# => 6

Key differences:

Aspectsumreduce
PurposeSpecifically for additionGeneral accumulation
ReadabilityIntuitive for sumsMore flexible but verbose
PerformanceOptimized for numeric sumsGeneral purpose overhead
Initial value default0 for numbersMust be specified

Floating Point Precision

Like all floating point arithmetic, sum inherits precision limitations:

[0.1, 0.2].sum
# => 0.30000000000000004

# For precise decimal arithmetic, use BigDecimal:
require 'bigdecimal'
[BigDecimal("0.1"), BigDecimal("0.2")].sum
# => 0.3

Practical Examples

Calculating Averages

Combine sum with count to calculate averages:

grades = [85, 90, 78, 92, 88]
average = grades.sum / grades.count
# => 86

Conditional Sum

Sum only elements matching a condition:

transactions = [100, -50, 200, -25, 150]

# Sum only positive transactions (income)
income = transactions.sum { |t| t > 0 ? t : 0 }
# => 450

# Sum only negative transactions (expenses)
expenses = transactions.sum { |t| t < 0 ? t : 0 }
# => -75

Totaling Prices with Tax

prices = [19.99, 29.99, 9.99]
tax_rate = 0.08

total_with_tax = prices.sum { |price| price * (1 + tax_rate) }
# => 64.57 (rounded display: $%.2f' % 64.57)

Counting Items by Category

inventory = [
  { item: "Apple", quantity: 50, price: 0.50 },
  { item: "Banana", quantity: 100, price: 0.20 },
  { item: "Orange", quantity: 75, price: 0.60 }
]

# Total inventory value
total_value = inventory.sum { |i| i[:quantity] * i[:price] }
# => 95.0

Summing Nested Arrays

matrix = [[1, 2], [3, 4], [5, 6]]

# Sum all elements
matrix.sum { |row| row.sum }
# => 21

# Sum with flatten
matrix.flatten.sum
# => 21

Performance Notes

sum has built-in optimizations for common cases:

# Ruby optimizes consecutive integer ranges using Gauss's formula
(1..1000000).sum
# => 500000500000 (instant, not a loop)

# For arrays of numbers, sum is faster than reduce(:+)
# because it avoids some Enumerable overhead

Return Value

sum returns the accumulated total:

  • Numbers: returns an Integer or Float depending on inputs
  • Strings: returns a concatenated String
  • Empty collection with default: returns 0
  • Empty collection with initial: returns that initial value

Edge Cases

# Single element
[5].sum
# => 5

# Single element with initial
[5].sum(10)
# => 15

# All zero values
[0, 0, 0].sum
# => 0

# Mixed positive and negative
[-10, 5, 3, -2].sum
# => -4

See Also