如何在Lua中原地过滤数组?需兼容ipairs迭代且索引从1开始
Lua 原地过滤数组(保持ipairs可迭代性)
刚好碰到过类似的需求,给你一个高效的原地过滤实现,完全符合你描述的要求:
function inplace_filter(arr, predicate) -- 用指针记录新数组的当前插入位置 local target_idx = 1 -- 遍历原数组(只处理ipairs能覆盖的连续部分) for _, elem in ipairs(arr) do if predicate(elem) then arr[target_idx] = elem target_idx = target_idx + 1 end end -- 把多余元素置为nil,确保数组从1开始连续 for i = target_idx, #arr do arr[i] = nil end end
代码说明
- 第一个循环用
ipairs遍历,完美匹配你定义的“数组”范围——从1开始的连续整数键,直到遇到nil为止。 - 满足判断条件的元素会被移动到
target_idx指向的位置,这个指针只在找到有效元素时递增,相当于在原数组内部“压缩”有效元素,不需要额外创建大的临时表。 - 第二个循环是核心:把
target_idx之后的所有位置设为nil,这样数组长度会被正确截断,ipairs迭代时会停在最后一个有效元素,不会出现断档。
测试示例
用你给出的例子验证一下:
local my_arr = {1, 5, 7} -- 定义判断函数:保留大于1的元素 local filter_func = function(elem) return elem > 1 end -- 调用原地过滤函数 inplace_filter(my_arr, filter_func) -- 用ipairs迭代验证 for i, val in ipairs(my_arr) do print(string.format("索引%d:%d", i, val)) end
运行后会输出:
索引1:5 索引2:7
完全符合预期,而且原数组被直接修改,没有额外开销。
注意事项
- 这个函数是原地修改原数组,不会返回新数组,调用后原数组内容直接更新。
- 传入的
predicate必须是接收单个元素参数、返回布尔值的函数,用于判断元素是否需要保留。 - 仅处理表中
ipairs可遍历的连续整数键部分,表内的非整数键或不连续整数键不会被改动。
内容的提问来源于stack exchange,提问作者VasiliNovikov
相关产品推荐
相关产品推荐

