vislee / leevis.com

Blog
87 stars 13 forks source link

lua 迭代器与泛型for #152

Open vislee opened 6 years ago

vislee commented 6 years ago

迭代器(iterator)是一种数据结构,能够遍历集合的每个元素。在lua中是一种支持指针类型的结构。

lua中熟知的迭代器有pairsipairs。通常配合泛型for同时使用。

例如:

a = {3, 1, 12}
for i, v in ipairs(a) do
    print(i, v)
end

我们自己也可以实现一个类似于ipairs的功能

function iter (a, i)
    i = i + 1
    local v = a[i]
    if v then
       return i, v
    end
end

function myipairs (a)
    return iter, a, 0
end

使用自定义的迭代器也可以实现类似ipairs的功能

for i, v in myipairs(a) do
    print(i,v)
end

通过自定义的迭代器函数可以看出是泛型for在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。

:loudspeaker: 注: 第二步是真正for循环的开始。第一步只是准备(如果理解了闭包,其实就是调用返回闭包)。迭代器返回的就是控制变量和控制变量对应的值,把上述自定义函数修改一下可能更容易理解。

function iter (a, i)
    local v = a[I+1]
    if v then
       return i+1, v
    end
end

自定义pairs迭代器:

function mypairs(a)
    return next, a, nil
end

自定义限制循环中增加table元素的迭代器

function xpairs(a)
    local size = table.maxn(a)

    local function iter(a, k)
        local t = table.maxn(a)
        if t > size then
            return
        end

        return next(a, k)
    end

    return iter, a, nil
end

--例如
local xx = {1, 2, 3, 4}
for k, v in xpairs(xx) do
    print(k, v)
    -- xx[#xx+1] = v+4
end

自定义限制循环次数的迭代器

function xpairs(a)
    local size = table.maxn(a)
    if size > 32 or size == 0 then
        size = 32
    end

    local t = 0

    local function iter(a, k)
        t = t + 1
        if t > size then
            return
        end

        return next(a, k)
    end

    return iter, a, nil
end