如何为Lua迭代器编写通用包装器以过滤返回值?
通用Lua迭代器过滤包装器实现方案
这个问题刚好戳中Lua迭代器的核心机制——咱们只要抓住迭代器的三个组成部分(迭代函数、状态变量、初始值),就能轻松写出支持任意返回值数量的通用过滤包装器。
核心思路
Lua的for循环迭代器本质依赖三个要素:迭代函数(每次调用返回下一组值)、状态变量(迭代过程中维持的状态)、初始值(迭代的起始输入)。咱们的包装器要做的就是:
- 拿到原迭代器的这三个核心组件
- 生成一个新的迭代函数,它会不断调用原迭代器,直到找到符合过滤条件的值组,或者迭代结束
通用包装器代码
function filtered_iter(filter, orig_func, ...) -- 获取原迭代器的三个核心组件 local iter, state, first_val = orig_func(...) -- 返回包装后的迭代器三组件 return function(s, last_var) while true do -- 调用原迭代函数,接收所有返回值到数组中 local values = {iter(s, last_var)} -- 数组为空说明迭代结束,直接返回 if #values == 0 then return end -- 用过滤函数判断是否保留当前值组 if filter(unpack(values)) then -- 返回符合条件的所有值 return unpack(values) end -- 更新迭代状态变量,继续下一轮循环 last_var = values[1] end end, state, first_val end
代码说明
filter:过滤函数,接收原迭代器返回的所有值,返回true则保留当前值组,false则跳过orig_func:你要包装的原始迭代器函数(比如问题中的otherfunc)...:传递给原始迭代器的所有参数(比如问题中的stuff)- 不管原迭代器返回1个还是N个值,代码都会通过可变参数和数组自动适配,完全通用
使用示例
先模拟一个原始迭代器:
-- 模拟返回x/y/z三组值的迭代器,x从1到5 function otherfunc(stuff) local x = 0 return function() x = x + 1 if x > 5 then return end return x, x*2, x+10 end end
然后用包装器过滤掉y>5的值组:
-- 定义过滤规则:只保留y≤5的组 local keep_small_y = function(x, y, z) return y <= 5 end -- 使用包装后的迭代器 for x, y, z in filtered_iter(keep_small_y, otherfunc, "test stuff") do print(string.format("x=%d, y=%d, z=%d", x, y, z)) end
运行结果:
x=1, y=2, z=11 x=2, y=4, z=12
灵活扩展
如果需要修改返回值(比如只返回部分值),只需在过滤函数通过后调整返回的内容即可。比如只想返回x和z:
return function(s, last_var) while true do local x, y, z = iter(s, last_var) if not x then return end if y <=5 then return x, z -- 只返回x和z end last_var = x end end, state, first_val
内容的提问来源于stack exchange,提问作者Phrogz
相关产品推荐
相关产品推荐

