100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Ruby

Arrays in Ruby

An in-depth look at Ruby's Array class — ordered, index-based collections that can hold mixed types and expose a huge Enumerable-powered method set.

Strings, Arrays & HashesBeginner10 min readJul 9, 2026
Analogies

Arrays in Ruby

An Array in Ruby is an ordered, integer-indexed collection that can hold objects of any type simultaneously — a single array can mix integers, strings, hashes, and even other arrays without complaint. Arrays are created with literal syntax ([1, 2, 3]), the Array.new constructor, or helper methods like Array(). Because Array includes the Enumerable module, it inherits dozens of powerful methods for searching, transforming, and reducing data, on top of the array-specific methods for indexing, insertion, and removal.

🏏

Cricket analogy: An Array is like a batting order card that can list a mix of specialist batters, bowlers, and even the wicketkeeper's name side by side without complaint, and because it's built on Enumerable, you can search or total up any stat across the whole list.

Creating and indexing arrays

Beyond the familiar literal syntax, Array.new(3) { |i| i * 2 } builds an array from a block, which is the safe way to create arrays of mutable default objects — this avoids the classic bug where Array.new(3, []) makes three references to the *same* empty array, so mutating one element mutates all of them. Indexing supports negative numbers to count from the end, and ranges or the two-argument array[start, length] form to slice out subarrays; out-of-bounds single-index access returns nil rather than raising.

🏏

Cricket analogy: Array.new(3) { |i| i * 2 } is like issuing each new fielder their own individual water bottle instead of one bottle passed around the whole slip cordon -- Array.new(3, []) would have all three sharing one bottle, so one fielder drinking from it empties it for everyone.

ruby
numbers = [10, 20, 30, 40, 50]
numbers[0]          # => 10
numbers[-1]         # => 50 (last element)
numbers[1..3]       # => [20, 30, 40]
numbers[1, 2]       # => [20, 30] (start, length)
numbers[10]         # => nil, no error

# safe construction with a block avoids shared references
grid = Array.new(3) { Array.new(3, 0) }
grid[0][0] = 1
grid # => [[1, 0, 0], [0, 0, 0], [0, 0, 0]] -- rows are independent

Mutating, querying, and Enumerable-powered methods

push/<< append to the end, pop removes and returns the last element, and shift/unshift operate on the front. For queries, compact strips out nil values, uniq removes duplicates, and flatten collapses nested arrays — flatten(1) limits the collapse to a single level of nesting, leaving deeper arrays intact. Because Array includes Enumerable, methods like map, select, reduce, and sum are also available and chainable, letting you express data pipelines declaratively instead of with manual accumulator variables.

🏏

Cricket analogy: push and pop are like adding or removing the last batter from the tail-end of a batting order, while compact is like removing 'did not bat' blanks from the scorecard and flatten(1) collapses a partnership's sub-list of runs into the main scoresheet, one level at a time.

ruby
stack = []
stack.push(1)
stack << 2 << 3        # << can be chained
stack.pop              # => 3, stack is now [1, 2]

data = [3, nil, 1, nil, 2, 1]
data.compact.uniq.sort  # => [1, 2, 3]

nested = [1, [2, 3, [4, 5]]]
nested.flatten(1)       # => [1, 2, 3, [4, 5]] -- only one level deep

# Enumerable-powered pipeline
orders = [{ amount: 40, status: :paid }, { amount: 15, status: :pending }]
orders.select { |o| o[:status] == :paid }.sum { |o| o[:amount] } # => 40

In JavaScript, arrays are also dynamically resizable and can hold mixed types, similar to Ruby — but Ruby's Array benefits from the shared Enumerable module, meaning the exact same map/select/reduce vocabulary works identically on Hash, Range, Set, and any custom class that implements each, which JavaScript arrays don't share with its Map or Set objects.

Array.new(3, some_object) creates three references to the *same* object, not three independent copies — mutating one element mutates all of them if the object is mutable (like an Array or Hash). Always prefer the block form Array.new(3) { some_object.dup } or Array.new(3) { [] } when the default value is mutable.

  • Ruby arrays are ordered, mixed-type, integer-indexed collections created via literals, Array.new, or Array().
  • Negative indices count from the end; single out-of-bounds index access returns nil instead of raising.
  • Array.new(n, default) shares one object reference across all slots — use the block form for independent mutable defaults.
  • Common mutators include push/<<, pop, shift, unshift, insert, and delete_at, each with array-position semantics.
  • compact, uniq, and flatten handle nil removal, deduplication, and nested-array flattening respectively.
  • Because Array includes Enumerable, map/select/reduce/sort_by/group_by all work directly on arrays and are chainable.

Practice what you learned

Was this page helpful?

Topics covered

#Ruby#RubyStudyNotes#Programming#ArraysInRuby#Arrays#Creating#Indexing#Mutating#DataStructures#StudyNotes#SkillVeris