2017-07-02 2 views
1

Disons que j'ai un dictionnaire Lua (soit une table Lua qui contient des index de type string) comme ceci:Est-il possible de faire un itérateur dans Lua qui peut parcourir un dictionnaire?

local my_dictionary = {a = 123; b = 321; c = 456; d = 654}; 

Ce que je suis en train de faire est de créer une fonction iterator qui peut itérer sur une table même si ses index sont de type chaîne; un peu comme des paires, cependant chaque fois que j'essaie d'appeler next() pour obtenir l'index suivant, la valeur retournera seulement l'index, la valeur si l'index est de type int. Une idée que j'ai eu était peut-être d'appeler (index): byte (1, -1) et d'additionner le tuple d'ints, et l'utiliser comme une sorte d'indice de simulation, juste pour garder une trace des index, mais je ne pense pas ça marcherait avec le prochain. Voici essentiellement ce que j'ai jusqu'à présent:

local function each(list) 
    if #list > 0 then 
     local function my_itr(lst, ind) 
      return next(lst, ind); 
     end 
     return my_itr, List, 0; 
    end 
    return function() end, nil, nil; 
end 

cela ne fonctionne que pour une table avec index int (une table de tableau), donc je me demandais si quelqu'un pouvait me aider. Merci. Edit: Pour rendre cette moins vague est un morceau exemple ici de code de ce que je suis en train d'accomplir:

local mytable = {a = 123; b = 321; 3, 2, 1, c = "bca"}; 
for i,v in each(mytable) do 
    print(i,v); 
end 

ce qu'il doit générer:

>a 123 
>b 321 
>1 3 
>2 2 
>3 1 
>c bca 

La sortie aurait pas à être commande exacte.

+0

Votre question est plutôt difficile à comprendre. Je peux * deviner * que vous voulez itérer les clés de chaîne dans l'ordre lexicographique, mais encore - pourriez-vous s'il vous plaît poster un exemple de ce que vous voulez réaliser, c'est-à-dire une table, un morceau de code et la sortie désirée? – iehrlich

+0

Bien sûr, je viens de l'éditer; Merci –

+2

Vous dites ci-dessus que vous voulez seulement renvoyer des index int, mais votre sortie prévue montre un comportement identique à 'paires()'. Lequel est-ce? BTW, cette page montre comment implémenter 'paires': https://www.lua.org/pil/7.3.html. – luther

Répondre

2

Il devrait fonctionner exactement comme vous le souhaitez avec quelques tweaks: CORRECTIF faute de frappe dans List et passer nil au lieu de 0:

local function each(list) 
    local function my_itr(lst, ind) 
    return next(lst, ind) 
    end 
    return my_itr, list, nil 
end 

local mytable = {a = 123; b = 321; 3, 2, 1, c = "bca"} 
for i,v in each(mytable) do 
    print(i,v) 
end 

Ce imprime ce qui suit pour moi, ce qui est ce que vous besoin:

1 3 
2 2 
3 1 
a 123 
b 321 
c bca 
2

Vous pouvez réaliser ce même comportement en utilisant pairs. Ne le confondez pas avec ipairs cependant - ce sont deux fonctions différentes de traversée de table!

Bien que ipairs traverse uniquement les clés entières de la table (habituellement il arrête également à la première clé de nombre entier non nul), pairs traverse toutes paires clé-valeur dans la table.

Ainsi, en écrivant

local mytable = {a = 123; b = 321; 3, 2, 1, c = "bca"}; 
for i, v in pairs(mytable) do 
    print(i, v); 
end 

Vous obtiendrez toutes les paires clé-valeur imprimée, dans un ordre aléatoire. Voici le demo. En tant que sidenote, il n'y a pas de 'dictionnaire' dans Lua - tous les tableaux associatifs sont appelés 'tables'.

+0

Je ne veux pas être impoli, et j'espère que cela ne semble pas impoli, mais cela ne répond pas à ma question; Je suis au courant de l'usine d'itérateur de paires; J'essaye de faire mon propre itérateur qui fonctionne comme des paires.Merci d'avoir aidé. –

+0

Pas grossier du tout. Donc, votre objectif est simplement de ré-implémenter les paires? Alors ok. Cela inclut-il de ré-implémenter 'next'? :) – iehrlich

+0

Eh bien au début, j'essayais seulement de ré-implémenter des paires; Mais maintenant que vous avez mentionné la prochaine, je suppose que si je voulais vraiment ré-implémenter des paires, je devrais aussi ré-implémenter ensuite, mais je ne suis pas sûr que vous puissiez ré-implémenter la prochaine sans entrer dans du code C. –