/ Tags: RUBY-CODE / Categories: SOLUTIONS

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]

Learn More

cdrrazan

Rajan Bhattarai

Full Stack Software Developer! 💻 🏡 Grad. Student, MCS. 🎓 Class of '23. GitKraken Ambassador 🇳🇵 2021/22. Works with Ruby / Rails. Photography when no coding. Also tweets a lot at TW / @cdrrazan!

Read More