私は渡された変数から空でない最初の文字列を返す関数を実装しようとしています。 最初の非nil、空でない文字列を返す関数を作成するにはどうすればよいですか?
function first_non_empty(...)
for i, item in ipairs({...}) do
if item ~= nil and item ~= '' then
return item
end
end
return ''
end
が動作しない素朴なアプローチので、残念ながら、これらの変数のいくつかは、nilに次のようになります。それがnil値を検出したとしてipairsとすぐ出て終了します。これは、変数をゼロにすることができないように要件を変更するか、長さを関数に渡してテーブル長を
ipairs
に依存させる必要がないようにするか、関数内のすべてのパラメータをラップしてそれらは明示的にゼロである。
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でなくてもよく、空でない文字列ではない最初のパラメータを返します。
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
ニース!ボーナスとして、 'select'が5.1に存在し、' table.pack'はそうではないので、これをScribuntoで使うことができます。 –
@ChrisMidgley 'function table.pack(...)return {n = select( '#'、...)、...} end'はすべてです。長いvarargリストの場合、 'select'呼び出しのためにリストを繰り返しコピーすることは、一度テーブルを作成してそれを反復するよりも遅くなるかもしれません。他の方向では、あとでガベージコレクションする必要があるテーブルを作成するのが遅くなる可能性があります。だからベンチマークはあなたのケースでどちらが速いかを知ることができます(あるいは速度が実際問題であることがわかるまでクリーナーだと思うものを選ぶだけです)。 – nobody