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

ParameterTypeDefaultDescription
blockProcRequiredA 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