Concaténation des tableaux en Lua

ORIGINAL POST

étant Donné qu'il n'existe pas de fonction intégrée en Lua, je suis à la recherche d'une fonction qui me permet d'ajouter des tables. J'ai googlé un peu et avez essayé toutes les solutions que j'ai découvert, mais aucune ne semble fonctionner correctement.

le scénario se passe comme ceci: j'utilise Lua embarqué dans une application. Une commande interne de l'application renvoie une liste de valeurs sous la forme d'un tableau.

ce que j'essaie de faire est d'appeler cette commande de façon récursive dans une boucle et d'ajouter les valeurs retournées, encore une fois sous la forme d'une table, à la table des itérations précédentes.


modifier

pour ceux qui rencontreront ce post dans le futur, veuillez noter ce que @gimf a posté. Comme les Tables de Lua ressemblent autant à des tableaux qu'à n'importe quoi d'autre (même dans un contexte de liste), il n'y a pas de véritable bonne manière d'ajouter une table à l'autre. Le concept le plus proche est la fusion des tables. Veuillez voir le post", " Lua - fusionner les tables? " pour les aider à cet égard.

26
demandé sur Community 2009-09-11 17:27:04

8 réponses

réponses trop compliquées?

voici mon implémentation:

function TableConcat(t1,t2)
    for i=1,#t2 do
        t1[#t1+1] = t2[i]
    end
    return t1
end
25
répondu Weeve Ferrelaine 2013-03-07 18:00:10

pour ajouter deux tableaux ensemble faire ceci

    ii=0
for i=#firsttable, #secondtable+#firsttable do
    ii=ii+1
    firsttable[i]=secondtable[ii]
end

utilisez la première table comme la variable que vous vouliez ajouter car le code ajoute la seconde à la fin de la première table dans l'ordre.

  • i est le numéro de début du tableau ou de la liste.
  • #secondtable+#firsttable est ce que à la fin.

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 de sorte qu'elle fonctionne avec n'importe quelle table ou liste de taille.

5
répondu Red_M 2012-10-29 02:35:44

en général, la notion de concaténation de tables arbitraires n'a pas de sens dans Lua parce qu'une seule clé ne peut avoir qu'une seule valeur.

il y a des cas particuliers où la concaténation a un sens. Un tel est pour les tableaux contenant des tableaux simples, qui pourraient être le résultat naturel d'une fonction destinée à retourner une liste de résultats.

Dans ce cas, vous pouvez écrire:

-- 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

C'est une copie, et ne cherche pas à savoir si une valeur userdata ou une valeur de fonction est un conteneur ou un objet quelconque qui pourrait nécessiter un traitement différent.

une implémentation alternative pourrait modifier le premier argument plutôt que de créer une nouvelle table. Cela permettrait d'économiser le coût de la copie, et de faire array_concat différent de l'opérateur .. sur les chaînes.

Edit: Comme l'a observé dans un commentaire de Joseph Kingry , j'ai omis d'extraire correctement la valeur réelle de chaque argument de ... . J'ai également échoué à retourner la table fusionnée de la fonction du tout. C'est ce que j'obtiens pour coder dans la boîte de réponse et ne pas tester le code du tout.

4
répondu RBerteig 2017-05-23 11:47:24

une façon 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
3
répondu warspyking 2015-02-23 03:27:56

si vous voulez fusionner deux tables, mais avez besoin d'une copie profonde de la table de résultat, pour quelque raison que ce soit, utilisez la fusion de une autre question sur la fusion des tables plus un code de copie profonde de lua-utilisateurs .

(edit Eh bien, peut-être que vous pouvez modifier votre question pour fournir un exemple minimal... Si vous voulez dire que la table

 { a = 1, b = 2 }

concaténé avec une autre table

{ a = 5, b = 10 }

devrait donner

{ a = 1, b = 2, a = 5, b = 10 }

alors vous n'avez pas de chance. Les touches sont uniques.

Il semble que vous voulez avoir une liste de paires, comme { { a, 1 }, { b, 2 }, { a, 5 }, { b, 10 } } . Vous pouvez également utiliser une structure finale comme { a = { 1, 5 }, b = { 2, 10 } } , selon votre application.

mais la simple notion de tables" concaténantes " n'a pas de sens avec les tables Lua. )

2
répondu gimpf 2017-05-23 11:47:24

Et d'une façon de plus:

for _,v in ipairs(t2) do 
    table.insert(t1, v)
end

Il me semble plus lisible, elle parcourt la 2ème tableau et ajoute ses valeurs pour le 1er, fin de l'histoire. Curieux comment il se déplace en vitesse à l'indexation explicite [] ci-dessus

2
répondu Nas Banov 2015-03-20 23:36:56

Voici une implémentation que j'ai faite similaire à celle de RBerteig ci-dessus, mais en utilisant le paramètre caché arg qui est disponible quand une fonction reçoit un nombre variable d'arguments. Personnellement, je pense que c'est plus lisible par rapport à la syntaxe 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
1
répondu Neil 2011-11-28 18:57:23

Voici mon implémentation pour concaténer un ensemble de tables d'indexation, FYI.

  1. définir une fonction pour concaténer deux tableaux, concat_2tables
  2. une autre fonction récursive concatenateTables : diviser la liste des tableaux par unpack , et appeler 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)  
    
1
répondu ouxiaogu 2015-10-23 07:01:00