find and detect return the first element that matches a block condition.

find `find` stops once the block returns true for one element.

Find Detect

threshold
find_detect.rb
Replay: real traced execution (multi-file project)
threshold = 6
numbers = [3, 5, 8, 11]

found = numbers.find do |number|
  number >= threshold
end

result = found || "none"

puts "threshold=#{threshold}"
puts "found=#{result}"
threshold = 4
numbers = [3, 5, 8, 11]

found = numbers.find do |number|
  number >= threshold
end

result = found || "none"

puts "threshold=#{threshold}"
puts "found=#{result}"
threshold = 10
numbers = [3, 5, 8, 11]

found = numbers.find do |number|
  number >= threshold
end

result = found || "none"

puts "threshold=#{threshold}"
puts "found=#{result}"
  1. threshold ← 6, numbers ← [3, 5, 8, 11]

    1threshold→ 6 = 6  #@threshold=4, 102numbers→ [3, 5, 8, 11] = [3, 5, 8, 11]34found = numbers[3, 5, 8, 11].find do |number|5  number >= threshold6end
  2. do |number|

    pass 1 of 3
    4found = numbers.find do |number3|5  number >= threshold6end
    All 3 passes — pass 1 is the card above
    passnumbernumbersfound
    13
    25
    38[3, 5, 8, 11]8
  3. result ← 8

    8result→ 8 = found8 || "none"910puts "threshold=#{threshold6}"11puts "found=#{result8}"
    outputthreshold=6
    found=8
  1. threshold ← 4, numbers ← [3, 5, 8, 11]

    1threshold→ 4 = 42numbers→ [3, 5, 8, 11] = [3, 5, 8, 11]34found = numbers[3, 5, 8, 11].find do |number|5  number >= threshold6end
  2. do |number|

    pass 1 of 2
    4found = numbers.find do |number3|5  number >= threshold6end
  3. found ← 5

    pass 2 of 2
    4found→ 5 = numbers[3, 5, 8, 11].find do |number5|5  number >= threshold6end
  4. result ← 5

    8result→ 5 = found5 || "none"910puts "threshold=#{threshold4}"11puts "found=#{result5}"
    outputthreshold=4
    found=5
  1. threshold ← 10, numbers ← [3, 5, 8, 11]

    1threshold→ 10 = 102numbers→ [3, 5, 8, 11] = [3, 5, 8, 11]34found = numbers[3, 5, 8, 11].find do |number|5  number >= threshold6end
  2. do |number|

    pass 1 of 4
    4found = numbers.find do |number3|5  number >= threshold6end
    All 4 passes — pass 1 is the card above
    passnumbernumbersfound
    13
    25
    38
    411[3, 5, 8, 11]11
  3. result ← 11

    8result→ 11 = found11 || "none"910puts "threshold=#{threshold10}"11puts "found=#{result11}"
    outputthreshold=10
    found=11

Stop at the First Match

  1. Start with numbers: [3, 5, 8, 11].
  2. find checks one number at a time.
  3. The first number at least threshold is returned.
  4. Later numbers are not needed after a match. | Checked number | >= 6? | What happens | | --- | --- | --- | | 3 | no | keep looking | | 5 | no | keep looking | | 8 | yes | return 8 | | 11 | not checked | already stopped |

Exercise: find_detect.rb

Use find to return the first number at or above a threshold, or none when nothing matches