Array#each_slice

Added in v3.0 · Updated March 13, 2026 · Array Methods
ruby array iteration slice windows

.each_slice(n) and .each_cons(n) are Array methods that iterate over consecutive elements in groups of a specified size. They differ in how they create those groups.

each_slice

each_slice creates non-overlapping groups of n elements. Each element appears in exactly one slice.

numbers = [1, 2, 3, 4, 5, 6, 7, 8]

numbers.each_slice(3) { |slice| p slice }
# Output:
# [1, 2, 3]
# [4, 5, 6]
# [7, 8]

When the array length is not evenly divisible by n, the last slice contains fewer elements.

each_cons

each_cons creates sliding windows of n consecutive elements. Each window overlaps with the previous one.

numbers = [1, 2, 3, 4, 5, 6, 7, 8]

numbers.each_cons(3) { |window| p window }
# Output:
# [1, 2, 3]
# [2, 3, 4]
# [3, 4, 5]
# [4, 5, 6]
# [5, 6, 7]
# [6, 7, 8]

Parameters

ParameterTypeDescription
nIntegerSize of each slice or window

Return Value

Both methods return an Enumerator if called without a block. This lets you chain other Enumerable methods.

# Using enumerator form
enum = [1, 2, 3, 4, 5, 6].each_slice(3)
enum.to_a  # => [[1, 2, 3], [4, 5, 6]]

# Chaining with map
result = [1, 2, 3, 4, 5, 6].each_slice(2).map(&:sum)
result  # => [3, 7, 11]

Practical Examples

Pagination

items = (1..15).to_a
page_size = 5

items.each_slice(page_size).with_index(1) do |page, index|
  puts "Page #{index}: #{page.inspect}"
end
# Page 1: [1, 2, 3, 4, 5]
# Page 2: [6, 7, 8, 9, 10]
# Page 3: [11, 12, 13, 14, 15]

Running averages

prices = [10, 20, 30, 40, 50]

averages = prices.each_cons(2).map { |a, b| (a + b) / 2.0 }
# => [15.0, 25.0, 35.0, 45.0]

Processing matrix rows

matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

# Convert columns to rows
matrix.transpose.each_slice(2) { |pair| p pair }

Common Mistakes

Forgetting that each_slice is non-overlapping while each_cons overlaps:

# Wrong: using each_cons for non-overlapping chunks
[1, 2, 3, 4].each_cons(2).to_a
# => [[1, 2], [2, 3], [3, 4]]  # 3 pairs, overlaps!

# Correct: each_slice for non-overlapping
[1, 2, 3, 4].each_slice(2).to_a
# => [[1, 2], [3, 4]]  # 2 chunks, no overlap

When to Use Which

  • each_slice: Paginating results, batch processing, creating groups
  • each_cons: Running calculations, sliding windows, comparing consecutive elements

See Also