Hash methods (keys, values, each) in Ruby - Time & Space Complexity
When we use hash methods like keys, values, and each, we want to know how long these actions take as the hash grows.
We ask: How does the time to run these methods change when the hash has more items?
Analyze the time complexity of the following code snippet.
my_hash = {a: 1, b: 2, c: 3, d: 4}
keys = my_hash.keys
values = my_hash.values
my_hash.each do |key, value|
puts "Key: #{key}, Value: #{value}"
end
This code gets all keys, all values, and then prints each key-value pair from the hash.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Traversing all items in the hash.
- How many times: Once for each method call, it goes through every key-value pair.
Each method looks at every item in the hash one time.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The work grows directly with the number of items. Double the items, double the work.
Time Complexity: O(n)
This means the time to run these methods grows in a straight line with the number of items in the hash.
[X] Wrong: "Hash methods like keys or values are instant no matter how big the hash is."
[OK] Correct: These methods must look at every item to collect keys or values, so they take longer as the hash grows.
Understanding how hash methods scale helps you write efficient code and explain your choices clearly in interviews.
"What if we used each_key instead of keys? How would the time complexity change?"
Practice
keys method do when called on a Ruby hash?Solution
Step 1: Understand the
Thekeysmethodkeysmethod extracts all keys from the hash and returns them as an array.Step 2: Compare with other methods
valuesreturns values,eachiterates pairs, so onlykeysreturns keys array.Final Answer:
Returns an array of all the keys in the hash -> Option CQuick Check:
keys= keys array [OK]
- Confusing keys with values method
- Thinking keys modifies the hash
- Mixing up keys with each method
h?Solution
Step 1: Identify correct block syntax for
The correct syntax uses curly braces or do-end with block parameters separated by a comma inside pipes:each{ |key, value| ... }.Step 2: Check each option
h.each { |key, value| puts key + value }uses correct syntax with pipes and comma. Others have syntax errors or wrong block format.Final Answer:
h.each { |key, value| puts key + value } -> Option BQuick Check:
Correct block syntax =h.each { |key, value| puts key + value }[OK]
- Omitting pipes around block parameters
- Missing comma between key and value
- Using arrow syntax incorrectly in blocks
h = {a: 1, b: 2, c: 3}
h.keysSolution
Step 1: Understand
Thekeysmethod on hashkeysmethod returns an array of all keys in the hash. Here keys are symbols :a, :b, :c.Step 2: Match output with options
[:a, :b, :c] matches the array of keys. [1, 2, 3] is values, C is the whole hash, D is invalid symbol array.Final Answer:
[:a, :b, :c] -> Option DQuick Check:
h.keys = [:a, :b, :c] [OK]
- Confusing keys with values output
- Expecting hash instead of array
- Misreading symbols as strings
h = {x: 10, y: 20}
h.each do |k v|
puts "#{k}: #{v}"
endSolution
Step 1: Check block parameter syntax
Block parameters must be separated by a comma inside pipes:|k, v|. Here comma is missing.Step 2: Verify other parts
Keys as symbols are valid,each do-endis valid, andputssyntax is correct.Final Answer:
Missing comma between block parameterskandv-> Option AQuick Check:
Block params need comma [OK]
- Omitting comma between block variables
- Thinking symbols are invalid keys
- Confusing block syntax with method call
h = {a: 1, b: 0, c: nil, d: 4}, which code snippet correctly returns an array of keys whose values are truthy (not false or nil)?Solution
Step 1: Understand filtering keys by truthy values
We want keys where values are truthy (not false or nil).selectfilters pairs by value truthiness.Step 2: Analyze each option
h.select { |k, v| v }.keysfilters hash pairs by truthy value, then gets keys -> [:a, :d] [check].h.keys.select { |k| k }checks if key truthy (all symbols are), returns all keys.h.values.select { |v| v }.keyscallskeyson array (NoMethodError).h.each { |k, v| k if v }.keysreturns original hash, no filtering.Final Answer:
h.select { |k, v| v }.keys -> Option AQuick Check:
Filter pairs then get keys =h.select { |k, v| v }.keys[OK]
- Trying to call keys on array of values
- Using each instead of select for filtering
- Selecting keys without checking values
Ready to prove it?
Pass the test and this pattern moves unknown
