ZetCode

Ruby Arrays

last modified October 18, 2026

An array is an ordered, integer-indexed collection of objects in Ruby. Arrays can hold values of any type, grow and shrink dynamically, and come with a rich set of methods for access, modification, iteration, and transformation. This guide covers how to create arrays, read and change their contents, iterate over them, and use the most common array methods.

Creating Arrays

Arrays can be created with literal brackets, with Array.new (given a size and an optional default value or block), or with the %w notation for lists of words. Ruby arrays may contain mixed element types. This example shows each creation style.

creating.rb
# Array literal
nums = [1, 2, 3, 4]
puts nums.inspect

# Array.new with size and default value
zeros = Array.new(3, 0)
puts zeros.inspect

# Array.new with size and block
squares = Array.new(5) { |i| i * i }
puts squares.inspect

# %w creates an array of words
fruits = %w[apple banana cherry]
puts fruits.inspect

# Mixed types
mixed = [1, "two", :three, 4.0, nil]
puts mixed.inspect
puts mixed.length

Array.new(5) { |i| i * i } calls the block once per index, so the block form is the way to build computed arrays. inspect shows the Ruby representation of an array, while puts on an array prints each element on its own line.

$ ./creating.rb
[1, 2, 3, 4]
[0, 0, 0]
[0, 1, 4, 9, 16]
["apple", "banana", "cherry"]
[1, "two", :three, 4.0, nil]
5

Accessing Elements

Elements are accessed by zero-based index. Negative indexes count from the end, ranges and start/length pairs return slices, and first, last, and fetch provide safer access. The dig method walks nested structures. Out-of-range indexes return nil rather than raising an error.

accessing.rb
colors = %w[red green blue yellow purple]

puts colors[0]          # first element
puts colors[-1]         # last element
puts colors[1..3].inspect   # slice by range
puts colors[1, 2].inspect   # slice by start and length
puts colors.first
puts colors.last(2).inspect
puts colors.fetch(10, "none")

nested = { user: { emails: ["a@example.com", "b@example.com"] } }
puts nested.dig(:user, :emails, 0)
data = [[1, [2, 3]], [4]]
puts data.dig(0, 1, 1)
puts colors[10].inspect

fetch accepts a default value for missing indexes, which avoids silent nil results. dig is useful for nested arrays and hashes: it returns nil instead of raising if an intermediate level is missing.

$ ./accessing.rb
red
purple
["green", "blue", "yellow"]
["green", "blue"]
red
["yellow", "purple"]
none
a@example.com
3
nil

Adding and Removing Elements

push and << append to the end, pop removes from the end, unshift and shift work at the front, insert adds at a given position, and delete, delete_at, and compact remove elements. These methods modify the array in place.

modifying.rb
a = [1, 2, 3]
a.push(4)
a << 5
puts a.inspect

last = a.pop
puts "popped #{last}: #{a.inspect}"

first = a.shift
puts "shifted #{first}: #{a.inspect}"

a.unshift(0)
puts a.inspect

a.insert(2, 99)
puts a.inspect

a.delete(99)
puts a.inspect

removed = a.delete_at(0)
puts "deleted #{removed}: #{a.inspect}"

b = [1, nil, 2, nil, 3]
puts b.compact.inspect

delete removes every element equal to the given value, whereas delete_at removes the element at a single index and returns it. compact returns a new array without nil values; it does not modify the receiver.

$ ./modifying.rb
[1, 2, 3, 4, 5]
popped 5: [1, 2, 3, 4]
shifted 1: [2, 3, 4]
[0, 2, 3, 4]
[0, 2, 99, 3, 4]
[0, 2, 3, 4]
deleted 0: [2, 3, 4]
[1, 2, 3]

Iteration

Ruby arrays are iterated with blocks. each visits every element, each_with_index also yields the index, map transforms each element into a new array, and select and reject filter elements by a condition.

iterating.rb
words = %w[ruby array list]

words.each { |w| puts w }

words.each_with_index do |w, i|
  puts "#{i}: #{w}"
end

nums = (1..10).to_a
puts nums.map { |n| n * 2 }.inspect
puts nums.select(&:even?).inspect
puts nums.reject(&:even?).inspect
puts nums.each_slice(3).to_a.inspect

map, select, and reject all return new arrays and leave the original unchanged. The &:even? form is a shorthand for a block that calls the named method on each element.

$ ./iterating.rb
ruby
array
list
0: ruby
1: array
2: list
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
[2, 4, 6, 8, 10]
[1, 3, 5, 7, 9]
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

Common Array Methods

Ruby provides many utility methods for arrays. flatten removes nesting, uniq removes duplicates, include? tests membership, zip pairs elements from several arrays, and take/drop split an array by count. Aggregates such as sum, min, and max summarize values, and join builds a string.

methods.rb
nested = [1, [2, [3, 4]]]
puts nested.flatten.inspect
puts nested.flatten(1).inspect

puts [1, 2, 2, 3, 3, 3].uniq.inspect
puts [1, 2, 3].include?(2)

names = %w[Ann Ben Cy]
ages = [30, 25, 41]
puts names.zip(ages).inspect

vals = [10, 20, 30, 40, 50]
puts vals.take(2).inspect
puts vals.drop(2).inspect

puts vals.sum
puts vals.min
puts vals.max
puts vals.join(", ")

flatten(1) limits flattening to one level. zip returns an array of pairs, which is convenient for iterating over parallel arrays.

$ ./methods.rb
[1, 2, 3, 4]
[1, 2, [3, 4]]
[1, 2, 3]
true
[["Ann", 30], ["Ben", 25], ["Cy", 41]]
[10, 20]
[30, 40, 50]
150
10
50
10, 20, 30, 40, 50

Sorting

Sorting arrays with sort, sort_by, and custom comparators is covered in a separate article: see Ruby sort array.

Source References

Learn more from these resources: Ruby Array Documentation, Array (Ruby 3.0), and Enumerable Documentation.

List all Ruby tutorials.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.