Ruby Array Methods Cheat Sheet
Ruby's `Enumerable` module gives `Array` a rich set of higher-order methods that replace most explicit loops. This snippet covers the trio you reach for daily (`map`, `select`, `reject`), reductions with `inject` / `reduce`, and grouping or slicing helpers like `group_by` and `each_slice`. Memorise these and most array transformations become a single chained pipeline.
1,066 views
22
nums = [1, 2, 3, 4, 5, 6]
squares = nums.map { |n| n * n }
p squares # [1, 4, 9, 16, 25, 36]
evens = nums.select { |n| n.even? }
p evens # [2, 4, 6]
odds = nums.reject { |n| n.even? }
p odds # [1, 3, 5]
# &:method shorthand: equivalent to { |x| x.method }
p nums.map(&:to_s) # ["1", "2", "3", "4", "5", "6"]map (alias collect) returns a new array of the block's return values. select (alias filter) keeps elements where the block is truthy; reject keeps elements where it is falsy. The &:method shorthand turns a symbol into a proc that calls the method on each element, equivalent to { |x| x.to_s } but shorter. Chain them freely: nums.map(&:to_s).select { |s| s.size > 1 } reads top-to-bottom as a pipeline. None of these mutate the original array; their ! counterparts (map!, select!) do, but prefer the non-mutating forms unless you have a specific reason.
nums = [1, 2, 3, 4, 5]
# Sum: classic accumulator. The first iteration uses the seed (0).
total = nums.inject(0) { |acc, n| acc + n }
puts "sum=#{total}"
# Without a seed, the first element becomes the initial accumulator.
product = nums.inject { |acc, n| acc * n }
puts "product=#{product}"
# Symbol form: nums.inject(:+) is the shortest sum.
puts "sum (sym) =#{nums.inject(:+)}"
puts "max =#{nums.inject(0) { |m, n| n > m ? n : m }}"
# Building a hash via inject is a common pattern.
pairs = [["ada", 36], ["linus", 54]]
ages = pairs.inject({}) { |h, (k, v)| h[k] = v; h }
p agesinject (alias reduce) walks the collection with an accumulator. With a seed, the block runs once per element starting from the seed; without a seed, the first element IS the seed and the block runs from the second element. The symbol form nums.inject(:+) is sugar for nums.inject { |a, b| a + b } and is the idiomatic way to sum or product. The hash-building idiom shows up everywhere; on Ruby 2.6+ you can replace it with pairs.to_h for the simple [[k, v], ...] shape, but inject is still the right tool when the value depends on prior accumulator state.
words = %w[apple ant banana cherry coconut]
# Bucket by first letter.
by_letter = words.group_by { |w| w[0] }
p by_letter
# {"a"=>["apple", "ant"], "b"=>["banana"], "c"=>["cherry", "coconut"]}
# Walk the array in fixed-size chunks (the last chunk may be shorter).
[1, 2, 3, 4, 5, 6, 7].each_slice(3) { |chunk| p chunk }
# [1, 2, 3]
# [4, 5, 6]
# [7]
# partition: returns [pass, fail] in one walk; faster than select+reject.
pass, fail = (1..10).partition { |n| n.even? }
p pass # [2, 4, 6, 8, 10]
p fail # [1, 3, 5, 7, 9]group_by returns a hash keyed by the block's return value, with each value being the array of elements that produced that key. It is the Ruby equivalent of Collectors.groupingBy in Java. each_slice(n) iterates in fixed-size chunks and is the right tool for batched processing (paginated API calls, fixed-size database inserts). partition is select and reject fused into one pass, returning both arrays in a destructuring assignment. Together with chunk_while and slice_when for run-based grouping, these cover almost every array reorganisation you encounter without writing a manual loop.
