rubyguides

Hash#value?

The value? method returns true if the given value is present anywhere in the hash, false otherwise.

Syntax

hash.value?(value)   # => true or false

Parameters

ParameterTypeDefaultDescription
valueObjectRequiredThe value to search for in the hash

Return Value

Returns true if value exists as a value in the hash, false if it does not.

Description

value? checks whether the given object appears as a value in the hash. Unlike key?, which is O(1), value? must scan all values in the hash — O(n) time.

The method has one alias: has_value?.

Since a hash can have the same value stored under multiple keys, value? only tells you that the value exists somewhere, not which key or keys hold it. Use key? or fetch to find or access the associated key.

Examples

Basic usage

scores = { alice: 95, bob: 82, carol: 95 }

scores.value?(95)   # => true
scores.value?(82)  # => true
scores.value?(70)  # => false

Detecting sentinel values

config = { timeout: nil, retries: 3, debug: false }

config.value?(nil)     # => true
config.value?(false)  # => true — even falsy values are found
config.value?(0)      # => false

Finding keys that share a value

Because value? does not reveal which keys hold a value, you need to search manually to find them:

inventory = { apples: 0, bananas: 0, grapes: 5 }

zero_items = inventory.select { |_k, v| v.zero? }.keys
# => [:apples, :bananas]

inventory.value?(0)   # => true

With mixed value types

mixed = { count: 1, ratio: 1.0, percent: "100%" }

mixed.value?(1)       # => true  — integer 1
mixed.value?(1.0)    # => true  — Float and Integer compare equal
mixed.value?("1")     # => false — string "1" is distinct

Performance

value? is O(n) — it checks every value in the hash until it finds a match. For large hashes this is slower than key?, which is O(1) on average.

If you need to call value? repeatedly on the same hash, build a set of values first:

value_set = Set.new(hash.values)
value_set.include?(target_value)  # O(1) after the initial O(n) build

Gotchas

Confusing value? with key?. value? checks values; key? checks keys:

scores = { alice: 95, bob: 82 }

scores.key?(95)       # => false — 95 is not a key
scores.value?(95)     # => true  — 95 is a value

Duplicate values. If multiple keys share the same value, value? returns true but does not tell you which keys:

h = { a: nil, b: nil }

h.value?(nil)    # => true
h.key?(nil)      # => false — nil is a value, not a key

Use select with a block to find which keys hold a specific value.

See Also