我正在尝试实现一个函数,该函数从传递给它的变量返回第一个非空字符串。不幸的是,其中一些变量可能是零,所以天真的方法
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,它返回那些非零且不是空字符串的第一个参数?
答案 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',表示没有非零,非空的字符串。