Ответ 1
Сложные ответы много?
вот моя реализация:
function TableConcat(t1,t2)
for i=1,#t2 do
t1[#t1+1] = t2[i]
end
return t1
end
ОРИГИНАЛЬНАЯ ПОЧТА
Учитывая, что в Lua нет встроенной функции, я ищу функцию, которая позволяет мне добавлять таблицы вместе. Я немного поработал в Google и пробовал все решения, которые я наткнулся, но никто не работает должным образом.
Сценарий выглядит следующим образом: я использую Lua, внедренную в приложение. Внутренняя команда приложения возвращает список значений в виде таблицы.
То, что я пытаюсь сделать, это вызвать эту команду рекурсивно в цикле и добавить возвращаемые значения, снова в виде таблицы, в таблицу из предыдущих итераций.
ИЗМЕНИТЬ
Для тех, кто сталкивается с этим сообщением в будущем, обратите внимание на то, что опубликовал @gimf. Поскольку таблицы в Lua так же похожи, как и массивы, чем что-либо еще (даже в контексте списка), нет реального правильного способа добавления одной таблицы в другую. Ближайшей концепцией является слияние таблиц. Пожалуйста, см. Сообщение, Lua - таблицы слияния?" для получения помощи в этом отношении.
Сложные ответы много?
вот моя реализация:
function TableConcat(t1,t2)
for i=1,#t2 do
t1[#t1+1] = t2[i]
end
return t1
end
Чтобы добавить две таблицы вместе, сделайте это
ii=0
for i=#firsttable, #secondtable+#firsttable do
ii=ii+1
firsttable[i]=secondtable[ii]
end
используйте первую таблицу в качестве переменной, которую вы хотели бы добавить, поскольку код добавляет вторую в конец первой таблицы в порядке.
i
- начальный номер таблицы или списка.#secondtable+#firsttable
- это то, с чем нужно закончить.Он начинается в конце первой таблицы, которую вы хотите добавить, и заканчивается в конце второй таблицы в цикле for
, поэтому он работает с любой таблицей или списком размеров.
В общем, понятие конкатенирования произвольных таблиц не имеет смысла в Lua, потому что один ключ может иметь только одно значение.
Существуют особые случаи, когда конкатенация имеет смысл. Один из них - для таблиц, содержащих простые массивы, что может быть естественным результатом функции, предназначенной для возврата списка результатов.
В этом случае вы можете написать:
-- return a new array containing the concatenation of all of its -- parameters. Scaler parameters are included in place, and array -- parameters have their values shallow-copied to the final array. -- Note that userdata and function values are treated as scalar. 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 end
Это неглубокая копия и не пытается выяснить, является ли значение 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
Если вы хотите объединить две таблицы, но вам нужна глубокая копия таблицы результатов, по какой-либо причине используйте слияние из другого вопроса SO о слиянии таблиц плюс некоторый глубокий код копирования из lua-users.
(изменить Ну, может быть, вы можете отредактировать свой вопрос, чтобы предоставить минимальный пример... Если вы имеете в виду, что таблица
{ 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. )
И еще один способ:
for _,v in ipairs(t2) do
table.insert(t1, v)
end
Мне кажется наиболее читаемым - он повторяет вторую таблицу и добавляет ее значения к 1-му, концу истории. Любопытно, как это ускоряет скорость до явного индексации [] выше
Вот реализация, которую я сделал аналогично RBerteig выше, но используя скрытый параметр arg, который доступен, когда функция получает переменное количество аргументов. Лично я считаю, что это более читаемо и синтаксис выбора.
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)}
Хотя я не уверен, насколько хорошо это с точки зрения производительности.