पाठ 5 / 25
Arrays, Hashes and Enumerable
Work with arrays and hashes using Enumerable methods.
Collections with a rich toolbox
Arrays are ordered and can hold any objects: [1, "two", :three]. Hashes map keys to values and preserve insertion order: { "Pune" => 2, "Delhi" => 1 }, with the symbol shorthand { city: "Pune", total: 1200 }, and Ruby 3.1's value omission { city:, total: } uses local variables of the same names. Missing keys return nil; fetch(:key) raises instead, and fetch(:key, default) or Hash.new(0) provide defaults. Both include the Enumerable module, giving dozens of methods: each, map, select/filter, reject, find, reduce/sum, count, group_by, partition, sort_by, min_by/max_by, tally, each_with_object, each_slice, zip, flat_map, any?, all? and none?. Methods ending in ! (such as sort!, map!, uniq!) modify the receiver in place; their non-bang versions return new objects. &:symbol is shorthand for a block that calls that method: names.map(&:upcase). Lazy enumerators (.lazy) handle large or infinite sequences efficiently.
Enumerable in action
Grouping, summing and tallying orders with no explicit loops.
orders = [
{ id: "o1", city: "Pune", total: 1200, paid: true },
{ id: "o2", city: "Delhi", total: 300, paid: false },
{ id: "o3", city: "Pune", total: 800, paid: true },
]
paid = orders.select { |o| o[:paid] }
revenue = paid.sum { |o| o[:total] } # 2000
by_city = orders.group_by { |o| o[:city] } # { "Pune" => [...], "Delhi" => [...] }
city_totals = by_city.transform_values { |list| list.sum { _1[:total] } } # Pune 2000, Delhi 300
largest = orders.max_by { |o| o[:total] }[:id] # "o1"
city_counts = orders.map { |o| o[:city] }.tally # { "Pune" => 2, "Delhi" => 1 }
unpaid, settled = orders.partition { |o| !o[:paid] }
stock = Hash.new(0)
%w[pen ink pen].each { |sku| stock[sku] += 1 } # { "pen" => 2, "ink" => 1 }
city = "Mumbai"
total = 950
new_order = { city:, total: } # value omission (Ruby 3.1+)
puts new_order.fetch(:city)
puts %w[pune delhi].map(&:capitalize).inspect # ["Pune", "Delhi"]Bang methods change the receiver
list.sort returns a new sorted array; list.sort! sorts list itself. Also note that some bang methods return nil when nothing changed (such as uniq!), so do not chain them.
त्वरित जाँच: What does `orders.map(&:id)` do?
- Deletes ids
- Calls the id method on each element and returns an array of the results
- Sorts by id
- It is a syntax error
Answer
Calls the id method on each element and returns an array of the results — &:symbol converts the method name into a block that calls it on each element.