Hash#flat_map
hash.map { |key, value| block } -> array Returns:
Array · Updated March 13, 2026 · Hash Methods hash transformation enumerable map
map, collect, and flat_map transform hash key-value pairs into arrays. map and collect are identical—they apply a block to each key-value pair and return an array of the results. flat_map does the same but automatically flattens any nested arrays in the results.
Syntax
hash.map { |key, value| block }
hash.collect { |key, value| block }
hash.flat_map { |key, value| block }
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
block | Proc | Required | A block receiving key and value. Return any value. |
Examples
Basic map usage
scores = { alice: 95, bob: 82, charlie: 78 }
# Get all names as strings
names = scores.map { |name, _score| name.to_s }
# => ["alice", "bob", "charlie"]
# Get all scores doubled
doubled = scores.map { |_name, score| score * 2 }
# => [190, 164, 156]
# collect is identical to map
scores.collect { |_name, score| score }
# => [95, 82, 78]
Using map to transform to key-value arrays
config = { host: "localhost", port: 8080 }
# Transform to array of [key, value] arrays
pairs = config.map { |key, value| [key, value] }
# => [[:host, "localhost"], [:port, 8080]]
# Transform to hash using to_h
config.map { |key, value| [key.to_s, value] }.to_h
# => {"host"=>"localhost", "port"=>8080}
Using flat_map for nested results
categories = { fruits: ["apple", "banana"], vegetables: ["carrot"] }
# map would return nested arrays
nested = categories.map { |_k, items| items }
# => [["apple", "banana"], ["carrot"]]
# flat_map flattens automatically
flat = categories.flat_map { |_k, items| items }
# => ["apple", "banana", "carrot"]
Practical example: generating options for a form
fields = { username: "text", email: "email", password: "password" }
# Generate HTML option tags
options = fields.flat_map do |name, type|
["<input type=\"#{type}\" name=\"#{name}\">"]
end
# => ["<input type=\"text\" name=\"username\">",
# "<input type=\"email\" name=\"email\">",
# "<input type=\"password\" name=\"password\">"]
Using map with to_h for hash transformation
user = { name: "alice", score: 95, active: true }
# Uppercase all keys
user.map { |k, v| [k.upcase, v] }.to_h
# => {:NAME=>"alice", :SCORE=>95, :ACTIVE=>true}
# Transform values
user.map { |k, v| [k, v.is_a?(String) ? v.upcase : v] }.to_h
# => {:name=>"ALICE", :score=>95, :active=>true}
Common Patterns
Converting hash to array of objects
students = { alice: 85, bob: 92 }
# Map to Struct-like hashes
students.map { |name, score| { name: name, score: score, passed: score > 80 } }
# => [{:name=>:alice, :score=>85, :passed=>true},
# {:name=>:bob, :score=>92, :passed=>true}]
Using flat_map for cartesian product
sizes = { color: ["red", "blue"], size: ["S", "M", "L"] }
# Generate all combinations
sizes.flat_map { |_k, values| values.product(sizes.values.first) }
# => ["red S", "red M", "red L", "blue S", "blue M", "blue L"]
Filtering and transforming in one pass
products = { laptop: 999, mouse: 29, keyboard: 79, monitor: 299 }
# Filter expensive items, then get names
expensive_names = products.filter_map { |name, price| name.to_s if price > 100 }
# => ["laptop", "monitor"]
# filter_map available in Ruby 2.7+
Using with sorting
rankings = { alice: 3, bob: 1, charlie: 2 }
# Get names sorted by score
sorted_names = rankings.sort_by { |_name, rank| rank }.map { |name, _rank| name }
# => [:bob, :charlie, :alice]
Differences from Array
Hash#map works on key-value pairs, so your block receives two arguments:
hash = { a: 1, b: 2 }
hash.map { |key, value| "#{key}: #{value}" }
# => ["a: 1", "b: 2"]
This differs from Array#map, which receives only the element.
See Also
- hash::each — Iterate over key-value pairs
- hash::values — Get all values as array