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
| Parameter | Type | Description |
|---|---|---|
| n | Integer | Size 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