Find/detect for first match in Ruby - Time & Space Complexity
When we look for the first item that matches a condition, we want to know how long it takes as the list grows.
We ask: How does the time to find the first match change when the list gets bigger?
Analyze the time complexity of the following code snippet.
numbers = [1, 3, 5, 8, 10]
result = numbers.find { |num| num.even? }
puts result
This code looks through the list to find the first even number and stops once it finds it.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Checking each number one by one to see if it is even.
- How many times: Up to the first even number found, or the whole list if none found.
As the list gets bigger, the time depends on where the first match is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Checks 1 to 10 items depending on first match |
| 100 | Checks 1 to 100 items depending on first match |
| 1000 | Checks 1 to 1000 items depending on first match |
Pattern observation: The time grows with the position of the first match, up to the full list size.
Time Complexity: O(n)
This means the time to find the first match grows linearly with the list size in the worst case.
[X] Wrong: "Finding the first match always takes the same time no matter the list size."
[OK] Correct: If the match is near the start, it's fast, but if it's near the end or missing, it takes longer as the list grows.
Understanding how searching stops early helps you explain efficient code and shows you know how loops behave with different inputs.
"What if we changed find to select to get all matches? How would the time complexity change?"
Practice
What does the Ruby method find (also known as detect) do when called on an array?
Solution
Step 1: Understand the purpose of
Thefindfindmethod searches through the array elements one by one.Step 2: Identify what
It returns the first element for which the block condition is true, then stops searching.findreturnsFinal Answer:
It returns the first element that matches the condition in the block. -> Option CQuick Check:
find= first matching element [OK]
- Thinking find returns all matches
- Confusing find with methods that modify the array
- Assuming find sorts the array
Which of the following is the correct syntax to find the first even number in an array nums using find?
nums = [1, 3, 4, 6]
Solution
Step 1: Recall the block syntax for
The block must be passed with curly braces or do-end and use a block variable with pipes.findStep 2: Check each option's syntax
nums.find { |n| n.even? } uses correct block syntax:{ |n| n.even? }. Others have syntax errors.Final Answer:
nums.find { |n| n.even? } -> Option AQuick Check:
Correct block syntax = nums.find { |n| n.even? } [OK]
- Missing pipes around block variable
- Passing condition without a block
- Using wrong arrow or syntax for block
What is the output of the following Ruby code?
words = ["apple", "banana", "cherry", "date"]
result = words.find { |w| w.length > 5 }
puts resultSolution
Step 1: Check each word's length
"apple" (5), "banana" (6), "cherry" (6), "date" (4).Step 2: Find first word with length > 5
"banana" is the first word longer than 5 characters.Final Answer:
"banana" -> Option DQuick Check:
First word with length > 5 = "banana" [OK]
- Choosing the last matching word instead of first
- Confusing length condition
- Assuming find returns all matches
Identify the error in this Ruby code that tries to find the first negative number:
numbers = [3, 5, -2, 7] result = numbers.find do |n| n < 0 end puts result
Solution
Step 1: Check block syntax
Thedo...endblock with variablenis valid syntax forfind.Step 2: Confirm method usage
findaccepts a block and returns the first element matchingn < 0.Final Answer:
There is no error; the code works correctly. -> Option AQuick Check:
Valid block syntax and method usage = There is no error; the code works correctly. [OK]
- Thinking only curly braces work for blocks
- Assuming variable must be declared outside block
- Believing find can't take blocks
You have an array of hashes representing people:
people = [
{name: "Alice", age: 18},
{name: "Bob", age: 17},
{name: "Carol", age: 22}
]Which code finds the first person who is an adult (age 18 or older) and returns their name?
Solution
Step 1: Understand the condition for adult
Adult means age 18 or older, so condition isp[:age] >= 18.Step 2: Find first matching person and get name
Usefindordetectwith condition, then access[:name].Step 3: Check options carefully
people.find { |p| p[:age] >= 18 }[:name] uses correct condition and returns name. people.detect { |p| p[:age] >= 18 }[:age] returns age, not name. Options A and C use > 18, excluding age 18.Final Answer:
people.find { |p| p[:age] >= 18 }[:name] -> Option BQuick Check:
Correct condition and return name = people.find { |p| p[:age] >= 18 }[:name] [OK]
- Using > 18 excludes age 18
- Returning age instead of name
- Confusing find and detect (both work but check return)
Ready to prove it?
Pass the test and this pattern moves unknown
