rubyguides

Array#each_index

array.each_index { |index| block } -> array

each_index iterates over an array by passing each element’s index to the block, rather than the element itself. This is the difference from Array#each, which passes elements.

Syntax

array.each_index { |index| block } -> array
array.each_index                    -> Enumerator

Examples

Basic Usage

fruits = ["apple", "banana", "cherry"]

fruits.each_index { |i| puts "Index: #{i}" }
# Index: 0
# Index: 1
# Index: 2
# => ["apple", "banana", "cherry"]

each_index vs each

This shows the key difference:

letters = ["a", "b", "c"]

# each gives you the element
letters.each { |elem| puts elem }
# a
# b
# c

# each_index gives you the index
letters.each_index { |i| puts i }
# 0
# 1
# 2

Building an index table

users = ["Alice", "Bob", "Carol"]

users.each_index { |i| puts "#{i + 1}. #{users[i]}" }
# 1. Alice
# 2. Bob
# 3. Carol

Accessing elements by index during iteration

names = ["John", "Jane", "Jim"]
ages  = [30, 25, 40]

names.each_index { |i| puts "#{names[i]} is #{ages[i]}" }
# John is 30
# Jane is 25
# Jim is 40

Modifying array elements at specific indices

numbers = [1, 2, 3, 4, 5]

# Double every element at even index
numbers.each_index { |i| numbers[i] *= 2 if i.even? }
numbers
# => [2, 2, 6, 4, 10]

With with_index (same pattern as each)

items = ["Alpha", "Beta", "Gamma"]

items.each_index.with_index(1) { |idx, num| puts "#{num}. #{idx}" }
# 1. 0
# 2. 1
# 3. 2

Return Value

each_index returns the array itself:

arr = [10, 20, 30]
result = arr.each_index { |i| puts i }
result.object_id == arr.object_id  # => true

When called without a block, it returns an Enumerator:

[1, 2, 3].each_index
# => #<Enumerator: [1, 2, 3]:each_index>

Common use cases

Parallel array iteration

When you have two arrays and need to iterate through them together by position:

products  = ["Widget", "Gadget", "Gizmo"]
prices    = [100, 50, 75]

products.each_index do |i|
  puts "#{products[i]}: $#{prices[i]}"
end
# Widget: $100
# Gadget: $50
# Gizmo: $75

Selective processing by index

data = [1, 2, 3, 4, 5]

# Process only even indices
data.each_index { |i| data[i] *= 10 if i.even? }
# => [10, 2, 30, 4, 50]

Building numbered output

tasks = ["Write tests", "Deploy app", "Update docs"]

tasks.each_index do |i|
  puts "[ ] #{i + 1}. #{tasks[i]}"
end
# [ ] 1. Write tests
# [ ] 2. Deploy app
# [ ] 3. Update docs

When to Use each_index vs each_with_index

MethodYieldsUse When
each_indexIndex onlyYou don’t need the element
each_with_indexElement and indexYou need both values
eachElement onlyIndex is irrelevant

If you need both element and index, each_with_index is often cleaner:

items = ["a", "b", "c"]

# With each_index - you fetch the element manually
items.each_index { |i| puts "#{i}: #{items[i]}" }

# With each_with_index - cleaner
items.each_with_index { |item, i| puts "#{i}: #{item}" }

For cases where you only need the index (not the element), each_index makes the intent explicit.

Performance

each_index has the same performance characteristics as each. There’s no meaningful overhead difference. Choose based on clarity of intent, not performance.

See Also