GGistDev

Arrays in Ruby

Ordered, dynamic collections; hold any object types.

Basics

Arrays are created with literals or constructors; indices can be negative to count from the end. Arrays can be nested.

arr = [1, "a", :ok]
empty = []
words = %w[ant bat cat]   # shortcut for array of strings
matrix = [[1,2],[3,4]]

Constructors and default pitfalls

Array.new(n, obj) uses the same object for all elements. Prefer the block form for distinct objects.

Array.new(3, [])        # => [[], [], []] (same object repeated!)
Array.new(3) { [] }     # => [[], [], []] (distinct arrays)

Indexing and slicing

Indices start at 0; negative indices count from the end. Slices return subarrays.

arr = [10, 20, 30, 40, 50]
arr[0]      # => 10
arr[-1]     # => 50
arr[1, 2]   # => [20, 30] (offset, length)
arr[1..3]   # => [20, 30, 40]
arr[2..]    # => [30, 40, 50]

Adding, removing, and updating

Use push/pop, unshift/shift, insert, delete operations, and slice assignment.

xs = [1,2,3]
xs << 4
xs.push(5)
xs.pop            # removes last
xs.unshift(0)     # add to front
xs.shift          # removes first

xs.insert(2, :x)  # insert at index
xs.delete(:x)     # remove all occurrences of :x
xs.delete_at(0)   # remove at index

xs[1, 2] = [:a, :b, :c]  # replace slice (can change length)

Transform and query

Non‑bang methods return new arrays; bang variants mutate in place.

[1,2,3].map { |n| n * 2 }      # => [2,4,6]
[1,2,3,4].select(&:even?)      # => [2,4]
[1,2,3].reject(&:odd?)         # => [2]
[1,2,3].reduce(:+)             # => 6

xs = [1,2,2,3]
xs.uniq!        # mutate to remove duplicates
xs.compact      # remove nils (non‑bang) => returns new array

Set‑like operations and sorting

Union, intersection, and difference operate element‑wise; sorting is stable and customizable.

[1,2] | [2,3]      # => [1,2,3]     (union)
[1,2] & [2,3]      # => [2]         (intersection)
[1,2,3] - [2]      # => [1,3]       (difference)
[3,1,2].sort       # => [1,2,3]
words.sort_by(&:length)  # custom key

Sampling and shuffling

[1,2,3,4].sample      # => random element
[1,2,3,4].sample(2)   # => 2 unique elements
[1,2,3,4].shuffle

Enumerators

Most methods return an Enumerator when no block is given; you can chain or iterate manually.

[1,2,3].map.with_index { |n, i| [i, n] }  # => [[0,1],[1,2],[2,3]]
[1,2,3].each   # => #<Enumerator: ...>

Summary

  • Dynamic, ordered containers with rich methods
  • Prefer functional methods (map, select) over manual loops when transforming
  • Beware Array.new(n, obj) aliasing; use the block form for distinct elements