Combine ipairs with an if guard to keep selected values.

guarded iteration A loop can visit every value while an `if` statement decides which values affect the accumulated result.

Filter Loop

limit
filter_loop.lua
Replay: real traced execution (multi-file project)
local limit = 4
local kept = 0
local last = 0

for _, value in ipairs({2, 4, 6, 8}) do
  if value >= limit then
    kept = kept + 1
    last = value
  end
end

print("limit=" .. limit)
print("kept=" .. kept)
print("last=" .. last)
local limit = 3
local kept = 0
local last = 0

for _, value in ipairs({2, 4, 6, 8}) do
  if value >= limit then
    kept = kept + 1
    last = value
  end
end

print("limit=" .. limit)
print("kept=" .. kept)
print("last=" .. last)
local limit = 6
local kept = 0
local last = 0

for _, value in ipairs({2, 4, 6, 8}) do
  if value >= limit then
    kept = kept + 1
    last = value
  end
end

print("limit=" .. limit)
print("kept=" .. kept)
print("last=" .. last)
  1. limit ← 4, kept ← 0, last ← 0

    1local limit→ 4 = 4 --@limit=3, 62local kept→ 0 = 03local last→ 0 = 0
  2. _, value in ipairs({2, 4, 6, 8}) do

    pass 1 of 4
    5for _1, value2 in ipairs({2, 4, 6, 8}) do6  if value >= limit then7    kept = kept + 1
    All 4 passes — pass 1 is the card above
    pass_value
    112
    224
    336
    448
  3. kept ← 1, last ← 4

    pass 1 of 3
    5for _, value in ipairs({2, 4, 6, 8}) do6  if value4 >= limit4 then7    kept→ 1 = kept + 18    last→ 4 = value49  end
    All 3 passes — pass 1 is the card above
    passvaluekeptlast
    140 14
    261 26
    382 38
  4. print("limit=" .. limit)

    12print("limit=" .. limit4)13print("kept=" .. kept3)14print("last=" .. last8)
    outputlimit=4
    kept=3
    last=8
  1. limit ← 3, kept ← 0, last ← 0

    1local limit→ 3 = 32local kept→ 0 = 03local last→ 0 = 0
  2. _, value in ipairs({2, 4, 6, 8}) do

    pass 1 of 4
    5for _1, value2 in ipairs({2, 4, 6, 8}) do6  if value >= limit then7    kept = kept + 1
    All 4 passes — pass 1 is the card above
    pass_value
    112
    224
    336
    448
  3. kept ← 1, last ← 4

    pass 1 of 3
    5for _, value in ipairs({2, 4, 6, 8}) do6  if value4 >= limit3 then7    kept→ 1 = kept + 18    last→ 4 = value49  end
    All 3 passes — pass 1 is the card above
    passvaluekeptlast
    140 14
    261 26
    382 38
  4. print("limit=" .. limit)

    12print("limit=" .. limit3)13print("kept=" .. kept3)14print("last=" .. last8)
    outputlimit=3
    kept=3
    last=8
  1. limit ← 6, kept ← 0, last ← 0

    1local limit→ 6 = 62local kept→ 0 = 03local last→ 0 = 0
  2. _, value in ipairs({2, 4, 6, 8}) do

    pass 1 of 4
    5for _1, value2 in ipairs({2, 4, 6, 8}) do6  if value >= limit then7    kept = kept + 1
    All 4 passes — pass 1 is the card above
    pass_valuelimitkeptlast
    112
    224
    33660 16
    44861 28
  3. kept ← 1, last ← 6

    pass 1 of 2
    5for _, value in ipairs({2, 4, 6, 8}) do6  if value6 >= limit6 then7    kept→ 1 = kept + 18    last→ 6 = value69  end
  4. kept ← 2, last ← 8

    pass 2 of 2
    5for _, value in ipairs({2, 4, 6, 8}) do6  if value8 >= limit6 then7    kept→ 2 = kept + 18    last→ 8 = value89  end
  5. print("limit=" .. limit)

    12print("limit=" .. limit6)13print("kept=" .. kept2)14print("last=" .. last8)
    outputlimit=6
    kept=2
    last=8

Follow the Filter

  1. limit starts as 4.
  2. The loop visits 2, 4, 6, and 8.
  3. Values at least 4 are kept.
  4. The kept values are 4, 6, and 8.
  5. kept becomes 3 and last becomes 8. | value | kept at limit 4? | last after step | | --- | --- | --- | | 2 | no | 0 | | 4 | yes | 4 | | 6 | yes | 6 | | 8 | yes | 8 |

Exercise: filter_loop.lua

Reproduce limit=4, kept=3, and last=8, then use the pinned limit variants 3 and 6 to predict kept=3 last=8 and kept=2 last=8.