如何创建一个返回传递给它的第一个非零,非空字符串的函数?

时间:2017-04-14 11:22:48

标签: lua lua-table

我正在尝试实现一个函数,该函数从传递给它的变量返回第一个非空字符串。不幸的是,其中一些变量可能是零,所以天真的方法

function first_non_empty(...)
    for i, item in ipairs({...}) do
        if item ~= nil and item ~= '' then
            return item
        end
    end
    return ''
end

不起作用:ipairs在遇到零值时立即退出。这可以通过更改要求来修复,以便变量不能为零,或者通过将长度传递给函数,因此表长度不必依赖ipairs,或者将所有参数包装在函数中所以它们都不是明确的nil

function first_non_empty_func(...)
    for i, func in ipairs({...}) do
        local item = func()
        if item ~= nil and item ~= '' then
            return item
        end
    end
    return ''
end

function fn(p)
    local f = function() return p end
    return f
end

-- change callers to first_non_empty_func(fn(a), fn(b), fn(c))

然而,这两种解决方案都使功能原型复杂化。是否存在一个函数采用有序的参数列表,其中一些可能是nil,它返回那些非零且不是空字符串的第一个参数?

3 个答案:

答案 0 :(得分:4)

使用table.pack,它会保留所有nil条目并返回n字段中的条目数:

function first_non_empty_pack(...)
    local t = table.pack(...)
    for i = 1, t.n do
        local item = t[i]
        if item ~= nil and item ~= '' then
            return item
        end
    end
    return ''
end

答案 1 :(得分:3)

select('#', ...)可用于获取提供的参数数量,因此这里有一个不使用table.pack的替代方案:

function first_non_empty_pack(...)
    for i = 1, select('#', ...) do
        local item = select(i, ...)
        if item ~= nil and item ~= '' then
            return item
        end
    end
    return ''
end

答案 2 :(得分:1)

更简单的方法是使用递归。没有创建额外的表等:

function first_non_empty(item, ...)
    if item ~= nil and item ~= '' then return item end
    return first_non_empty(...)
end

但是列表必须以一些结束标记结束。例如,boolean'false',表示没有非零,非空的字符串。