2017-07-25 1 views
1

Dans Lua 4, de nombreuses tables ont une propriété "n" qui suit le nombre d'éléments à l'intérieur de la table.Lua 4 propriété "n" des tables

Toutes les tables ont-elles cette propriété? Peut-il être outrepassé?

Je demande, parce que j'essaye de développer une routine qui imprime récursivement tous les éléments d'une table dans la syntaxe valide de Lua, et veut savoir s'il est sûr de filtrer tous les "n" éléments du résultat?

Merci.

[modifier]

Voici le script:

-- ThoughtDump v1.4.0 
-- Updated: 2017/07/25 
-- ***************** 
-- Created by Thought (http://hw2.tproc.org) 
-- Updated by Mikali 

-- DESCRIPTION 
-- *********** 
-- Parses the globals table and __TDPrints its contents to "HW2.log". 
-- Can also be used to parse (i.e., pretty-print) generic tables in some cases. 

-- Note: functions & variables must actually be declared in order to be parsed. 
-- Otherwise, they are ignored. 
-- Note: if parsing a table other than the globals table, the __TDPrinted table 
-- values may be in a different order than was originally written. Values with 
-- numerical indices are moved to the "top" of the table, followed by values 
-- with string indices, followed by tables. Functions appear in different 
-- locations, depending on whether they are indexed using a number or a string. 
-- Note: despite the fact that nil values cannot be stored in tables, they are 
-- still handled. 
-- Note: even though functions may be referenced within tables, a function will 
-- only be parsed correctly if it is indexed using a string that is the same as 
-- the name of the function. 

__TDOutputString = "" 

function __TDParse(name, value, level, verbose, numbers, collapse) 
    if ((name == "__TDParse") or (name == "__TDSortHash") or (name == "__TDPrint") or (name == "__TDPrintGlobals()") or (name == "__TDOutputString")) then 
     return 
    end 
    local Element = nil 
    local ValType = type(value) 
    local NamType = type(name) 
    local PreLevel = "" 
    if (collapse == 0) then 
     for i = 1, level do 
      PreLevel = PreLevel .. "\t" 
     end 
    end 
    local ComLevel = "" 
    if (level ~= 0) then 
     ComLevel = "," 
    end 
    if ((ValType == "function") or (ValType == "userdata")) then 
     if (NamType == "string") then 
      Element = PreLevel .. name .. " = " .. name .. ComLevel 
     elseif (numbers == 1) then 
      Element = PreLevel .. "[" .. name .. "] = " .. name .. ComLevel 
     else 
      Element = PreLevel .. name .. ComLevel 
     end 
    elseif (ValType == "string") then 
     if (NamType == "string") then 
      Element = PreLevel .. name .. " = \"" .. value .. "\"" .. ComLevel 
     elseif (numbers == 1) then 
      Element = PreLevel .. "[" .. name .. "] = \"" .. value .. "\"" .. ComLevel 
     else 
      Element = PreLevel .. "\"" .. value .. "\"" .. ComLevel 
     end 
    elseif (ValType == "number") then 
     if (NamType == "string") then 
      Element = PreLevel .. name .. " = " .. value .. ComLevel 
     elseif (numbers == 1) then 
      Element = PreLevel .. "[" .. name .. "] = " .. value .. ComLevel 
     else 
      Element = PreLevel .. value .. ComLevel 
     end 
    elseif (ValType == "table") then 
     if (NamType == "string") then 
      Element = PreLevel .. name .. " =" 
     elseif (numbers == 1) then 
      Element = PreLevel .. "[" .. name .. "] =" 
     else 
      Element = "" 
     end 
    elseif (ValType == "nil") then 
     if (NamType == "string") then 
      Element = PreLevel .. name .. " = nil" .. ComLevel 
     elseif (numbers == 1) then 
      Element = PreLevel .. "[" .. name .. "] = nil" .. ComLevel 
     else 
      Element = PreLevel .. "nil" .. ComLevel 
     end 
    else 
     Element = PreLevel .. "-- unknown object type " .. ValType .. " for object " .. name 
    end 
    if (verbose == 1) then 
     Element = Element .. " -- " .. ValType .. ", tag: " .. tag(value) 
    end 
    if (((ValType == "table") and (NamType == "number") and (numbers == 0)) or (collapse == 1)) then 
     __TDPrint(Element, 0) 
    else 
     __TDPrint(Element, 1) 
    end 
    if (ValType == "table") then 
     __TDPrint(PreLevel .. "{", collapse == 0) 
     __TDSortHash(__TDParse, value, level + 1, verbose, numbers, collapse) 
     __TDPrint(PreLevel .. "}" .. ComLevel, 1) 
    end 
end 

function __TDSortHash(func, tabl, level, verbose, numbers, collapse) 
    local typesarray = {} 
    local typescount = {} 
    local keycount = 1 
    local keyarray = {} 
    for i, iCount in tabl do 
     local thistype = type(iCount) 
     if not (typesarray[thistype]) then 
      typescount[thistype] = 0 
      typesarray[thistype] = {} 
     end 
     typescount[thistype] = typescount[thistype] + 1 
     typesarray[thistype][typescount[thistype]] = i 
    end 
    sort(typesarray) 
    for i, iCount in typesarray do 
     sort(iCount) 
     for j, jCount in iCount do 
      keyarray[keycount] = tostring(jCount) 
      keycount = keycount + 1 
     end 
    end 
    for i, iCount in keyarray do 
     local tempcount = tonumber(iCount) 
     if (tempcount) then 
      iCount = tempcount 
     end 
     func(iCount, tabl[iCount], level, verbose, numbers, collapse) 
    end 
end 

function __TDPrint(instring, newline) 
    __TDOutputString = __TDOutputString .. instring 
    if (newline == 1) then 
     __TDOutputString = __TDOutputString .. "\n" 
    end 
end 

function __TDPrintGlobals() 
    __TDOutputString = "" 
    __TDPrint("globals =", 1) 
    __TDPrint("{", 1) 
    __TDSortHash(__TDParse, globals(), 1, 0, 0, 0) 
    __TDPrint("}\n", 1) 
    local WriteFile = "$test_globals_write.lua" 
    writeto(WriteFile) 
    write(__TDOutputString) 
    writeto() 
end 

__TDPrintGlobals() 

Répondre

1

Toutes les tables ont cette propriété. Il peut être écrasé. Pourquoi ne pas traverser la table en utilisant une boucle for? Ou si possible, utilisez Lua 5.3;)

Dans Lua, cela s'appelait table pour boucle, dans le langage Lua moderne, on l'appelle générique pour boucle.

La table pour l'instruction traverse toutes les paires (index, valeur) d'une table donnée. Il a la syntaxe suivante:

stat ::= for name `,' name in exp1 do block end 

A pour déclaration comme

for index, value in exp do block end 

est équivalent au code:

do 
    local _t = exp 
    local index, value = next(t, nil) 
    while index do 
     block 
     index, value = next(t, index) 
    end 
    end 

Notez les points suivants:

  • _t est une variable invisible. Le nom est ici à titre explicatif seulement.

  • Le comportement est indéfini si vous affectez à l'index à l'intérieur du bloc.

  • Le comportement n'est pas défini si vous modifiez la table _t pendant la traversée.
  • L'indice et la valeur des variables sont locaux à l'instruction; vous ne pouvez pas utiliser leurs valeurs après la fin for.

  • Vous pouvez utiliser break pour quitter a. Si vous avez besoin de la valeur de l'index ou de la valeur, assignez-les à d'autres variables avant de les casser.

  • L'ordre de passage des éléments de la table est indéfini, même pour les indices numériques. Si vous souhaitez parcourir les indices dans l'ordre numérique, utilisez un chiffre pour .

Référez-vous au manuel Lua 4.4.4

https://www.lua.org/manual/4.0/manual.html#4.4

+0

J'utilise 'for' boucles comme vous le suggérez.C'est un vieux jeu qui utilise Lua 4 et je ne peux pas le changer. Après quelques tests, il semble que le paramètre 'n' ne soit ajouté que lorsque j'utilise la fonction' tinsert' pour insérer des valeurs dans la table, et pas autrement. Une solution pourrait donc être de ne jamais utiliser 'tinsert'. – posfan12