ORIGINAL POST
Étant donné qu’il n’existe pas de fonction intégrée dans Lua, je suis à la recherche d’une fonction qui me permette d’ajouter des tableaux. J'ai beaucoup cherché sur Google et j'ai essayé toutes les solutions que j'ai découvertes, mais aucune ne semble fonctionner correctement.
Le scénario est le suivant: j'utilise Lua intégré à une application. Une commande interne de l'application renvoie une liste de valeurs sous la forme d'une table.
Ce que j'essaie de faire, c'est d'appeler cette commande de manière récursive dans une boucle et d'ajouter les valeurs renvoyées, à nouveau sous la forme d'une table, à la table des itérations précédentes.
MODIFIER
Pour ceux qui rencontreront ce message à l’avenir, veuillez noter ce que @gimf a publié. Comme les tableaux de Lua ressemblent autant à des tableaux qu'à toute autre chose (même dans un contexte de liste), il n’existe pas de méthode correcte pour ajouter un tableau à un autre. Le concept le plus proche est la fusion des tables. S'il vous plaît voir le post, " Lua - merge tables? " pour l'aide à cet égard.
Trop de réponses trop?
voici ma mise en oeuvre:
function TableConcat(t1,t2)
for i=1,#t2 do
t1[#t1+1] = t2[i]
end
return t1
end
Pour ajouter deux tables, faites ceci
ii=0
for i=#firsttable, #secondtable+#firsttable do
ii=ii+1
firsttable[i]=secondtable[ii]
end
utilisez la première table car la variable que vous vouliez ajouter en tant que code ajoute la seconde à la fin de la première table dans l'ordre.
i
est le numéro de départ de la table ou de la liste.#secondtable+#firsttable
est ce qu'il faut finir.Il commence à la fin de la première table que vous souhaitez ajouter et se termine à la fin de la deuxième table dans une boucle for
afin que cela fonctionne avec n'importe quelle table ou liste de tailles.
En général, la notion de concaténation de tables arbitraires n'a pas de sens en Lua car une clé unique ne peut avoir qu'une seule valeur.
Il existe des cas spéciaux dans lesquels la concaténation a du sens. L'une d'elles concerne les tableaux contenant des tableaux simples, qui pourraient être le résultat naturel d'une fonction destinée à renvoyer une liste de résultats.
Dans ce cas, vous pouvez écrire:
-- renvoie un nouveau tableau contenant la concaténation de tous ses paramètres --. Les paramètres du scaler sont inclus à la place, et les valeurs du tableau -- sont copiées peu profondes dans le tableau final . -- Notez que les données utilisateur et les valeurs de fonction sont traitées comme des scalaires . Function array_concat (.. .) local t = {} pour n = 1, sélectionnez ("#", ...) do arg local = select (n, ...) si type (arg) == "table" alors pour _, v dans ipairs (arg) do t [# t + 1] = v fin autre t [# t + 1] = arg fin fin retourne t end
Ceci est une copie superficielle et n'essaie en aucun cas de savoir si une valeur userdata
ou une fonction est un conteneur ou un objet quelconque nécessitant un traitement différent.
Une autre implémentation pourrait modifier le premier argument plutôt que de créer une nouvelle table. Cela réduirait les coûts de copie et rendrait array_concat
différent de l'opérateur ..
sur les chaînes.
Modifier: Comme observé dans un commentaire de Joseph Kingry , je n'ai pas réussi à extraire correctement la valeur réelle de chaque argument à partir de ...
. J'ai également échoué à renvoyer la table fusionnée à partir de la fonction du tout. C'est ce que je reçois pour coder dans la zone de réponse et ne pas tester le code du tout.
Un moyen simple de faire ce que vous voulez:
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
Et une autre manière:
for _,v in ipairs(t2) do
table.insert(t1, v)
end
Cela me semble le plus lisible - il parcourt la deuxième table et ajoute ses valeurs à la première, la fin de l'histoire. Curieux de voir à quel point il se comporte rapidement comme l'indexation explicite [] ci-dessus
Si vous souhaitez fusionner deux tables, mais que vous avez besoin d'une copie complète de la table de résultats, pour une raison quelconque, utilisez la fusion de une autre question SO sur la fusion de tables plus du code de copie complète de lua- utilisateurs .
(edit Eh bien, vous pouvez peut-être modifier votre question pour donner un exemple minimal ... Si vous voulez dire qu'un tableau
{ a = 1, b = 2 }
concaténé avec une autre table
{ a = 5, b = 10 }
devrait aboutir à
{ a = 1, b = 2, a = 5, b = 10 }
alors vous n'avez pas de chance. Les clés sont uniques.
Il semble que vous souhaitiez avoir une liste de paires, telle que { { a, 1 }, { b, 2 }, { a, 5 }, { b, 10 } }
. Vous pouvez également utiliser une structure finale telle que { a = { 1, 5 }, b = { 2, 10 } }
, selon votre application.
Mais la simple notion de "concaténation" de tableaux n’a aucun sens avec les tableaux de Lua .)
Voici une implémentation que j'ai faite similaire à celle de RBerteig ci-dessus, mais utilisant le paramètre caché arg qui est disponible lorsqu'une fonction reçoit un nombre variable d'arguments. Personnellement, je pense que ceci est plus lisible que la syntaxe choisie.
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
Voici mon implémentation pour concaténer un ensemble de tables d’indexation d’entiers purs, FYI.
concat_2tables
une autre fonction récursive concatenateTables
: divise la liste de tables en unpack
et appelle concat_2tables
pour concaténer table1
et 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)
Si vous voulez concaténer une table existante dans une nouvelle, c'est la manière la plus concise de le faire:
local t = {3, 4, 5}
local concatenation = {1, 2, table.unpack(t)}
Bien que je ne sois pas sûr de la qualité de cette performance.