Y a-t-il un moyen facile de créer une collection de dictionnaire, c'est-à-dire
E.g. Après p> existe-t-il un moyen de le faire sans p> t [k2] code> devrait évaluer à
vrai code>.
Également t code> lui-même doit être utilisable comme une clé de la même manière. P>
k1 code> et
k2 code> à cordes? (C'est ce que je fais actuellement.) li>
ol> p>
5 Réponses :
Vous pouvez mettre en œuvre et définir la méthode __eq dans la métabilité des deux tables.
k1 = {'a','b','c'} k2 = {'a','b','c'} mt1={__eq=function(a,b) for k,v in pairs(a) do if b[k]~=v then return false end end for k,v in pairs(b) do if a[k]~=v then return false end end return true end } setmetatable(k1,mt1) setmetatable(k2,mt1) assert(k1==k2,"Table comparison failed") function newDict(orig) if orig then return orig else local mt2={} local lookup ={} -- lookup table as upvalue to the metamethods mt2.__newindex = function(t,k,v) -- Registering a new table if type(k)~="table" then return end if v then -- v ~= false local found for idx,val in pairs(lookup) do if k==val then found=1 break end -- If already seen, skip. end if not found then lookup[#lookup+1]=k -- not seen before, add end else -- v == false or nil local to_erase for idx,val in pairs(lookup) do -- Assume there is only one match in the dict. if k==val then lookup[k]=nil break end --don't continue after this, next will be confused. end end end mt2.__index = function(t,k) -- looking up a table for idx,val in pairs(lookup) do if k==val then return true end end return false end return setmetatable({},mt2) end end t1 = newDict() t2 = newDict() k1={1,2,3} k2={"a"} k3={"z","d","f"} k1b={1,2,3} k2b={"a"} k3b={"z","d","f"} setmetatable(k1,mt1) setmetatable(k2,mt1) setmetatable(k3,mt1) setmetatable(k1b,mt1) setmetatable(k2b,mt1) setmetatable(k3b,mt1) -- Test multiple entries in 1 dict t1[k1]=true t1[k2]=true assert(t1[k1b],"t1[k1b] did not return true") assert(t1[k2b],"t1[k2b] did not return true") -- Test confusion between 2 dicts t2[k3]=true assert(not t1[k3b],"t1[k3b] did return true") assert(not t2[k1b],"t2[k1b] did return true")
Je vois que cela fait k1 == k2 code> vrai, mais ce n'est pas le même que
t [k1] == t [k2] code>
T = SETMETATINABLE ({}, {__ index = fonction (t, k) retour k extrémité}) code> fait que cela se produit pour vous.
C'est un piratage qui fonctionnera s'il n'y a qu'un seul tableau t code> par processus. En fait, j'ai trois tables de ce type qui doivent être indépendamment des tables vers d'autres valeurs.
Totalement changé pour correspondre aux spécifications exactement. Des choses que vous pourriez envisager de changer: le fonctionnement de l'égalité des tables; raccourci pour les tables qui sont littéralement les mêmes (même pointeur); Métaditable jonglant pour garder les métables d'origine des tables comparées.
Cette section ("Les clés sont des références") indique que les touches sont des références aux objets afin d'utiliser Un tableau identique comme dans votre exemple ne fonctionnera pas. Je pense que la façon dont vous faites en train de le faire peut être le meilleur moyen, mais je pourrais me tromper. P>
Si vous pouvez supporter une dépendance de la bibliothèque, vous pouvez utiliser quelque chose comme PenLight qui semble offrir des ensembles http://penlight.luaforge.net/#t10 . P>
Afaict que la bibliothèque ne fait pas ce que je veux, c'est-à-dire autoriser deux tables (ou ensembles ou cartes, etc.) à traiter comme des touches équivalentes i>. Comme les bibliothèques vont, je pense Sano est un meilleur match (il fait ce que je veux pour " tuples "mais pas des ensembles / mappages arbitraires, encore.)
Si les tables à utiliser à mesure que les touches sont corrigées et que leur contenu ne change pas, vous pouvez créer un Digest SHA2 sur la demande dans un Newindex em> métaméthod pour t code> et utilisez le Digestez comme la clé réelle. Le digest serait mis en cache dans une autre table indexée par les tables réelles. P>
Serializing Les deux tables dans Strings sont la solution Roberto Ierusalimschy (chef architecte de Lua) recommande d'indexer par contenu dans Programmation de Lua 2nd Edition EM>. P>.
Si toutes vos tables de clé sont des tableaux de chaînes (sans nulls incorporés), cela peut être effectué rapidement avec table.concat (t, '\ 0') code>. (Évidemment, votre table devra être trié si Vous voulez une identité indépendante index.) p>
Est le résultat de table.concat code> trié par les touches?
Vous voulez dire "si toutes vos valeurs i> sont des chaînes et des clés sont des entiers consécutifs à partir de 1 ...." table.concat code> ne fait rien avec le non-tableau partie d'une table.