You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:48:32