rubyguides

Hash#values_at

Hash#values_at returns an array containing the values for the given keys. It lets you look up multiple keys in one call and returns values in the same order as the keys you passed.

Basic Usage

scores = { alice: 95, bob: 87, carol: 92, dave: 88 }

scores.values_at(:alice, :carol)
# => [95, 92]

scores.values_at(:bob, :dave, :eve)
# => [87, 88, nil]

Keys that do not exist return nil. The returned array always has the same length as the input keys array.

Signature

values_at(*keys)

Accepts one or more keys and returns an array of values in the same order. Keys can be any type a Ruby hash supports — symbols, strings, numbers, objects.

Single and Multiple Keys

config = { host: "localhost", port: 5432, ssl: true }

# Single key
config.values_at(:host)
# => ["localhost"]

# Multiple keys
config.values_at(:host, :port, :missing_key)
# => ["localhost", 5432, nil]

Common Use Cases

Selecting specific fields from a hash

user = { id: 1, name: "Alice", email: "alice@example.com", role: "admin", created_at: "2024-01-15" }

user.values_at(:name, :email, :role)
# => ["Alice", "alice@example.com", "admin"]

This is cleaner than chaining multiple [] lookups or fetch calls.

With array of keys

keys = [:name, :email]
user.values_at(*keys)
# => ["Alice", "alice@example.com"]

Splat (*) expands an array into argument list. Useful when keys come from another array or variable.

Safe access in data processing

row = { "SKU" => "A-001", "price" => 29.99, "qty" => 100 }

row.values_at("SKU", "price", "qty", "discount")
# => ["A-001", 29.99, 100, nil]

Missing keys return nil rather than raising an error, making this useful for optional fields.

Comparison with Other Methods

MethodBehavior
values_at(*keys)Returns array of values, nil for missing keys
fetch(*keys)Returns values, raises KeyError for missing keys
dig(:key, :subkey, ...)Follows a nested path into the hash
valuesReturns all values as an array

Use values_at when you know the keys you want and want a clean array result. Use fetch when missing keys should be an error.

When Keys Are Missing

h = { a: 1, b: 2 }

h.values_at(:a, :z, :b)
# => [1, nil, 2]

nil appears in the result for any key that does not exist. This is not an error. If you need different handling for missing keys, use fetch with a default:

h.values_at(:a, :z, :b).map { |v| v || 0 }
# => [1, 0, 2]

See Also