元の投稿
Luaには組み込み関数がないため、テーブルを一緒に追加できる関数を探しています。私はかなりグーグルし、偶然見つけたすべての解決策を試しましたが、どれも適切に機能していないようです。
シナリオは次のようになります。私は、アプリケーションに埋め込まれたLuaを使用しています。アプリケーションの内部コマンドは、値のリストをテーブルの形式で返します。
私がやろうとしていることは、ループ内でそのコマンドを再帰的に呼び出し、返された値を再びテーブルの形式で、前の反復からのテーブルに追加することです。
[〜#〜]編集[〜#〜]
将来この投稿に遭遇した場合は、@ gimfが投稿した内容に注意してください。 Luaのテーブルは他の何よりも配列に似ているため(リストコンテキストであっても)、あるテーブルを別のテーブルに追加する実際の正しい方法はありません。最も近い概念は、テーブルのマージです。この点については、「 Lua-merge tables? "」の投稿をご覧ください。
過度に複雑な答えは?
これが私の実装です:
function TableConcat(t1,t2)
for i=1,#t2 do
t1[#t1+1] = t2[i]
end
return t1
end
2つのテーブルを一緒に追加するには、これを行います
ii=0
for i=#firsttable, #secondtable+#firsttable do
ii=ii+1
firsttable[i]=secondtable[ii]
end
最初のテーブルを、追加したい変数として使用します。コードでは、2番目のテーブルを最初のテーブルの最後に順に追加します。
i
は、テーブルまたはリストの開始番号です。#secondtable+#firsttable
は何で終わるかです。追加する最初のテーブルの最後から始まり、for
ループの2番目のテーブルの最後で終わります。これにより、任意のサイズのテーブルまたはリストで機能します。
一般に、任意のテーブルを連結するという概念はLuaでは意味がありません。単一のキーは1つの値しか持てないためです。
連結が意味をなす特別な場合があります。そのようなものの1つは、単純な配列を含むテーブルの場合です。これは、結果のリストを返すことを目的とした関数の自然な結果である可能性があります。
その場合、次のように書くことができます:
-すべての -パラメータの連結を含む新しい配列を返します。スケーラーパラメーターが所定の場所に含まれており、配列 -パラメーターの値は最終的な配列に浅くコピーされています。 -ユーザーデータと関数の値はスカラーとして扱われます。 function array_concat(...) local t = {} for n = 1、select( "#"、...)do local arg = select(n 、...) if type(arg)== "table" then for _、v in ipairs(arg)do t [#t + 1] = v end else t [#t + 1] = arg end end return t 終わり
これは浅いコピーであり、userdata
または関数の値が、異なる処理を必要とする可能性のあるコンテナまたはオブジェクトであるかどうかを確認しようとはしません。
別の実装では、新しいテーブルを作成するのではなく、最初の引数を変更する場合があります。これにより、コピーのコストが節約され、array_concat
が文字列の..
演算子とは異なります。
編集:Joseph Kingry のコメントにあるように、...
から各引数の実際の値を適切に抽出できませんでした。また、関数からマージされたテーブルを返すこともできませんでした。これは、解答ボックスでコーディングしてコードをテストしないことで得られるものです。
あなたが望むことをする簡単な方法:
local t1 = {1, 2, 3, 4, 5}
local t2 = {6, 7, 8, 9, 10}
local t3 = {unpack(t1)}
for I = 1,#t2 do
t3[#t1+I] = t2[I]
end
そしてもう一つの方法:
for _,v in ipairs(t2) do
table.insert(t1, v)
end
それは私にとって最も読みやすいもののようです-2番目のテーブルを反復処理し、その値を最初の1つに追加します。上記の明示的なインデックス付け[]にどの程度の速度で進んでいるのか知りたい
2つのテーブルをマージしたいが、何らかの理由で結果テーブルの詳細なコピーが必要な場合は、 another SOマージテーブルに関する質問 プラス lua-users からコードをディープコピーします。
(editさて、多分あなたは質問を編集して最小限の例を提供することができます...
{ a = 1, b = 2 }
別のテーブルと連結
{ a = 5, b = 10 }
結果になるはずです
{ a = 1, b = 2, a = 5, b = 10 }
その後、あなたは運が悪いです。 キーは一意です。
{ { a, 1 }, { b, 2 }, { a, 5 }, { b, 10 } }
のようなペアのリストが必要なようです。アプリケーションによっては、{ a = { 1, 5 }, b = { 2, 10 } }
のような最終的な構造を使用することもできます。
しかし、「連結」テーブルという単純な概念の概念は、Luaテーブルでは意味がありません。 )
これは、上記のRBerteigと同様に実行した実装ですが、関数が可変数の引数を受け取ったときに使用できる隠しパラメーターargを使用しています。個人的には、select構文よりも読みやすいと思います。
function array_concat(...)
local t = {}
for i = 1, arg.n do
local array = arg[i]
if (type(array) == "table") then
for j = 1, #array do
t[#t+1] = array[j]
end
else
t[#t+1] = array
end
end
return t
end
純粋な整数のインデックステーブルのセットを連結するための実装は、FYIです。
concat_2tables
別の再帰関数concatenateTables
:テーブルリストをunpack
で分割し、concat_2tables
を呼び出してtable1
とrestTableList
を連結します
t1 = {1, 2, 3}
t2 = {4, 5}
t3 = {6}
concat_2tables = function(table1, table2)
len = table.getn(table1)
for key, val in pairs(table2)do
table1[key+len] = val
end
return table1
end
concatenateTables = function( tableList )
if tableList==nil then
return nil
elseif table.getn(tableList) == 1 then
return tableList[1]
else
table1 = tableList[1]
restTableList = {unpack(tableList, 2)}
return concat_2tables(table1, concatenateTables(restTableList))
end
end
tt = {t1, t2, t3}
t = concatenateTables(tt)
既存のテーブルを新しいテーブルに連結したい場合は、これが最も簡潔な方法です。
local t = {3, 4, 5}
local concatenation = {1, 2, table.unpack(t)}
これがパフォーマンスに関してどれほど優れているかはわかりませんが。