Build A Hash From Two Parallel Arrays In Ruby
Two arrays — one of keys, one of values, lined up by index — is a shape that comes out of CSV headers plus a row, form field names plus submitted values, and column names plus a database row. Turning them into a hash is a one-liner.
Description
zip pairs the two arrays into an array of two-element arrays, and to_h converts that into a hash. keys.zip(values).to_h is the whole technique.
to_h also accepts a block, which lets you transform each pair on the way in — handy for symbolizing keys or coercing values without a second pass.
Mismatched lengths do not raise. zip pads the shorter side with nil, so guard the lengths yourself when a mismatch means bad input.
Sample input:
headers = ["name", "email", "age"]
values = ["Ada", "[email protected]", "36"]
Sample Output:
{ name: "Ada", email: "[email protected]", age: 36 }
Answer
headers = ["name", "email", "age"]
values = ["Ada", "[email protected]", "36"]
headers.zip(values).to_h
# => { "name" => "Ada", "email" => "[email protected]", "age" => "36" }
# Symbolize keys and coerce values in one pass
headers.zip(values).to_h do |key, value|
[key.to_sym, value.match?(/\A\d+\z/) ? value.to_i : value]
end
# => { name: "Ada", email: "[email protected]", age: 36 }
# Guard against a length mismatch
raise ArgumentError, "length mismatch" unless headers.size == values.size
# Mismatched lengths pad with nil rather than raising
["a", "b", "c"].zip([1, 2]).to_h
# => { "a" => 1, "b" => 2, "c" => nil }
# Reverse — split a hash back into parallel arrays
hash = { name: "Ada", age: 36 }
hash.keys # => [:name, :age]
hash.values # => ["Ada", 36]
Check viewARU - Brand Newsletter!
Newsletter to DEVs by DEVs - boost your Personal Brand & career! 🚀