rubyguides

Hash#rassoc

Hash#rassoc searches a hash for a given value and returns the matching key-value pair as a two-element array [key, value]. It is the reverse of Hash#assoc — where assoc searches by key, rassoc searches by value.

The method is handy when the value is what you know and the key is what you need next. That comes up in reverse lookups, lookup tables, and small maps where the value is unique enough to identify the record you want.

Basic Usage

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

scores.rassoc(87)
# => [:bob, 87]

scores.rassoc(100)
# => nil

When a match is found, the key and value are returned together. When no match exists, rassoc returns nil. Think of it as a reverse dictionary lookup: given what you have (the value), the method hands back the associated key so you can use it immediately in downstream logic.

Signature

rassoc(value)

Returns the first key-value pair where the value matches the given argument. The search proceeds in insertion order and stops on the first match. This means rassoc is deterministic: given the same hash and the same argument, it always returns the same pair. The order guarantee is helpful when the hash is built from user input or configuration data that carries meaning in its sequence.

searching with different value types

products = {
  "SKU-001" => "Widget",
  "SKU-002" => "Gadget",
  "SKU-003" => "Widget Pro"
}

products.rassoc("Widget")
# => ["SKU-001", "Widget"]

products.rassoc("Gadget")
# => ["SKU-002", "Gadget"]

Works with strings, numbers, symbols, arrays, or any object type that supports ==.

That flexibility is useful because rassoc does not care what kind of object sits in the value position. If the value compares equal, the pair is returned. This is especially helpful when values in the hash come from different sources, such as config files or API responses, and you cannot guarantee their exact class. In reverse lookups where performance is not the primary concern, the method’s straightforward semantics make the code easier to reason about.

comparing with other hash methods

MethodSearches byReturns
assockey[key, value] or nil
rassocvalue[key, value] or nil
keyvaluekey or nil
fetchkey (with default)value or default
dignested key pathvalue or nil

Use rassoc when you have a value and need the corresponding key. This comes up when building inverse mappings or looking up records by a non-key field.

It is not the fastest way to search a large hash, but it is straightforward and expressive when the table is small or when the lookup happens infrequently.

Limitations

Only returns the first match. If multiple entries share the same value, only the first one in insertion order is returned:

names = { alice: "Engineer", bob: "Designer", carol: "Engineer" }

names.rassoc("Engineer")
# => [:alice, "Engineer"]
# carol is not reached

Linear search. The hash is scanned from the beginning, making this O(n) regardless of hash size. For large hashes with frequent lookups, consider maintaining a reverse index. Building one is straightforward with invert, but keep in mind that invert also keeps only the last key for each duplicate value, so the index has the same first-match-only limitation as rassoc itself.

# Build a reverse index for O(1) lookup by value
scores = { alice: 95, bob: 87, carol: 92 }
by_score = scores.invert
by_score[87]  # => :bob

With a reverse index in place, rassoc-style lookups become constant-time operations. This is the standard workaround when the hash is large and the lookup happens frequently enough that linear scanning would be noticeable.

No block form. Unlike select or find, there is no variant that accepts a block.

See Also