Nearly all Ruby data, from JSON to Rails params, is handled as arrays and hashes.
An Array is an ordered, growable list of any objects: nums = [3, 1, 2]. Index from the front or back (nums[0], nums[-1]), slice with nums[0, 2] or nums[1..], and add with push/<<, unshift, pop, shift. Out-of-range reads return nil; fetch(i) raises instead. %w[a b c] builds an array of strings.
A Hash maps keys to values and keeps insertion order. With symbol keys, use the shorthand { name: "Ada", age: 36 }; other keys use =>: { "id" => 1 }. Note that :name and "name" are different keys, a common source of nil surprises with parsed JSON.
h[:missing]returnsnil(or the hash's default);h.fetch(:k)raisesKeyError, andh.fetch(:k, 0)gives a fallback.Hash.new(0)makes missing keys read as 0, perfect for counters. For mutable defaults use the block formHash.new { |h, k| h[k] = [] }.key?,keys,values,delete,merge,dig(:a, :b)andto_aare everyday tools.
Ranges like 1..5 (inclusive) and 1...5 (exclusive end) represent intervals; endless 1.. and beginless ..10 work too. Convert with to_a, test membership with include? or cover?.
Destructure arrays with first, *rest = list. Since Ruby 3.1 you can omit a hash value when a local variable has the same name: { name:, age: }.
Example
nums = [3, 1, 2]
nums << 5
p nums[-1], nums[1..2], nums[10] # 5, [1, 2], nil
first, *rest = nums
p first, rest # 3, [1, 2, 5]
user = { name: "Ada", "role" => "admin" }
p user[:name], user["name"] # "Ada", nil: symbol != string
p user.fetch(:age, 0) # 0
counts = Hash.new(0)
%w[a b a c a].each { |w| counts[w] += 1 }
p counts # {"a" => 3, "b" => 1, "c" => 1}
groups = Hash.new { |h, k| h[k] = [] }
groups[:even] << 2
p groups # {even: [2]}
name, age = "Bo", 7
p({ name:, age: }) # {name: "Bo", age: 7}
p (1...4).to_a, (1..).first(2) # [1, 2, 3], [1, 2]Remember
- Symbol keys and string keys are different
- Use fetch when a missing key is a bug; Hash.new(0) for counters
- Ranges: .. includes the end, ... excludes it
Watch out for
- Using Hash.new([]) for grouping: every key shares the same array object. Use the block form.