2017-09-09 3 views
1

J'ai un problème, Je dois changer une valeur dans une table connue qui se trouve dans n tables avant. Quelque chose comme ceci:Lua obtenir la valeur d'une table dans n tables

Box = { 
     {Name = "",Box = {{Name = "",Box = {{Name = "", Box = {{Name = "This must be change for the test",Box = {}}}}}}}} 
    } 

Pour changer cela, je peux hardcode cela avec:

Box[1].Box[1].Box[1].Box[1].Name = "Changed" 

Mais ce n'est pas la façon dont je le veux! Je veux changer cela dynamiquement, de sorte que j'ai une fonction qui peut changer la valeur 'x' du tableau 'n' dans le tableau principal 'tbl'.

Y at-il un moyen de le faire?

+0

'local t, n = _G, 4; pour j = 1, n do t = t.Box [1] end; t.Name = "Changé" ' –

+0

@EgorSkriptunoff, cela devrait suffire pour la réponse; J'ai mesuré;) –

+0

@PaulKulchenko - Mais il s'intègre bien dans un commentaire en ligne! :-) –

Répondre

0

Avec le problème comme cela, vous devriez probablement repenser vos choix de conception. Cette table dans n tables, vous décrivez est semblable à un arbre graphique où le champ box contient les références aux nœuds enfants. Comme vos commentaires l'indiquent, vous avez besoin de modifier un noeud situé sur un chemin dynamique dans cet arbre. Une fonction simple est évidente:

local function follow_path(start_node, path,i) 
    --takes start node and array of indices to follow 
    --returns table that is stored in the box-tree at this path 
    --i is for internal recursion 
    i=i or 1 
    if not path[i] then 
    return start_node 
    else 
    local new_start=start[path[i]] 
    assert(new_start,"No node is on this path") 
    return follow_path(new_start,path,i+1) 
    end 
end 
local function follow_path_and_rename(start_node,path,field_name,new_value) 
    local box = follow_path(start_node,path) 
    box[field_name] = new_value 
end 

Mais, selon le pourquoi avez-vous besoin de modifier un nœud avec le chemin dynamique il pourrait y avoir des approches plus solides. Une chose qui n'a jamais fait mal est de donner à chacun de vos boîtes un identifiant unique lors de sa création:

local new_box 
do 
local box_count=0 
new_box = function(name) 
    box_count=box_count+1 
    local box = { 
    unique_id=box_count, 
    name=name, 
    box={} 
    } 
    return box 
end 
end 

Avec cela, vous pouvez par exemple créer table d'index où vos boîtes sont toujours accessibles par leur id:

local index={} 
local add_new_box = function(name) 
    local box = new_box(name) 
    index[ box.unique_id] = box 
    return box 
end 

Si cela n'est pas acceptable, vous pouvez toujours rechercher dans les nœuds de l'arborescence un nœud dont la valeur unique est garantie.

Mais le fait est que toutes les tables ont déjà un identifiant unique. C'est leur adresse, la valeur qui est affectée à a lorsque vous faites a = {}. Les seules différences entre cela, et le unique_id sont: 1) a n'est pas tout à fait aussi lisible. 2) si vous connaissez a, vous n'avez pas besoin de le chercher.

Alors, jetez un oeil à votre problème, jetez un oeil et demandez-vous:? « Si ce besoin provient de Pourquoi ne puis-je obtenir unique_id à la place une série d'indices Pourquoi ne puis-je obtenir le même box au lieu de unique_id? "