Comment puis-je savoir si un tableau est un tableau?
Je suis l'élaboration d'un simple optimisé JSON fonction. Lua utilise des tables pour représenter des tableaux, mais en JSON j'ai besoin de reconnaître entre eux. Le code ci-dessous est utilisé:
t={
a="hi",
b=100
}
function table2json(t,formatted)
if type(t)~="table" then return nil,"Parameter is not a table. It is: "..type(t) end
local ret=""--return value
local lvl=0 --indentation level
local INDENT=" " --OPTION: the characters put in front of every line for indentation
function addToRet(str) if formatted then ret=ret..string.rep(INDENT,lvl)..str.."\n" else ret=ret..str end end
addToRet("{")
lvl=1
for k,v in pairs(t) do
local typeof=type(v)
if typeof=="string" then
addToRet(k..":\""..v.."\"")
elseif typeof=="number" then
addToRet(k..":"..v)
end
end
lvl=0
addToRet("}")
return ret
end
print(table2json(t,true))
Comme vous pouvez le voir dans le JSON de référence d'un object
est ce qu'on appelle un table
en Lua et il est différent d'un array
.
La question est de savoir comment je peux détecter si un tableau est utilisé comme un tableau?
- Une solution est de passer par toutes les paires et voir si ils n'ont numériques consécutives touches, mais ce n'est pas assez rapide.
- Une autre solution est de mettre un drapeau dans le tableau qui dit que c'est un tableau n'est pas un objet.
Pas plus simple/la meilleure solution?
OriginalL'auteur AlexStack | 2011-09-23
Vous devez vous connecter pour publier un commentaire.
Si vous voulez rapide, simple, non-intrusive solution plus de l'époque, alors je dirais juste vérifier index 1 - s'il existe, le tableau est un tableau. Bien sûr, il n'y a aucune garantie, mais dans mon expérience, les tables ont rarement la fois numérique et d'autres touches. Si c'est acceptable pour vous confondre certains objets pour les tableaux et si vous vous attendez à ce que cela arrive souvent, tout dépend de votre scénario d'usage - je suppose que c'est pas bon pour general librairie JSON.
Edit: Pour la science, je suis allé voir comment Lua CJSON fait les choses. Il passe par toutes les paires et vérifie si toutes les clés sont des entiers tout en gardant le maximum de clés (de la fonction correspondante
lua_array_length
). Puis il décide de sérialiser le tableau comme un tableau ou un objet en fonction de la façon clairsemée le tableau est (le ratio est contrôlé par l'utilisateur) c'est à dire un tableau avec des indices 1,2,5,10 va probablement être sérialisé comme un tableau tandis que d'une table avec des indices 1,2,1000000 ira comme un objet. Je suppose que c'est en fait assez bonne solution.OriginalL'auteur sbk
Non, il n'est pas intégré dans le moyen de les différencier, car en Lua il n'y a pas de différence.
Il y a déjà existant JSON bibliothèques, ce qui a probablement déjà le faire (par exemple. Lua CJSON.
D'autres options sont
__newindex
tels que de nouveaux numérique et indices subséquents sont autorisés à être utilisés.OriginalL'auteur jpjacobs
@AlexStack
Ce code est erroné, si échoue lorsque l'un des elemets est
false
.Je pense que l'ensemble de l'expression peut être changé à
type(t[i]) == nil
, mais il reste échoue dans certains scénarios, car il ne prendra pas en charge néant valeurs.Une bonne solution, je pense, est en train d'essayer avec
ipairs
ou à vérifier si#t
est égal àcount
, mais#t
retourne 0 avec des objets et descount
sera de zéro avec des tableaux vides, donc il peut avoir besoin d'un supplément de vérifier au début de la fonction, quelque chose comme:if not next(t) then return true
.Au passage, je suis coller une autre mise en œuvre, trouvé en lua-cjson (par Mark Pulford):
OriginalL'auteur Juan Ramirez
La plus simple de l'algorithme de différencier les tableaux/non-tableaux est celui-ci:
Explication ici: https://web.archive.org/web/20140227143701/http://ericjmritz.name/2014/02/26/lua-is_array/
Cela dit, vous aurez toujours des problèmes avec les tables vides sont - ils des "tableaux" ou "hashs"?
Pour le cas particulier de la sérialisation json, ce que je fais est de marquage des tableaux avec un champ dans leur métatable.
OriginalL'auteur kikito
Ici, c'est plus simple test basé sur Lua spécifique #len fonction de mécanisme.
function is_array(tbl) return type(tbl) == 'table' and (#tbl > 0 or next(tbl) == nil) end
.OriginalL'auteur feod0r
Grâce. J'ai développé le code suivant et ça fonctionne:
Êtes-vous sûr? Si l'index de la table n'est pas en continu...
Alors ce n'est pas un tableau.
OriginalL'auteur AlexStack
J'ai écrit cette fonction pour la jolie impression lua tables, et avait pour résoudre le même problème. Aucune des solutions ici compte pour les cas limites, comme certaines touches de chiffres, mais d'autres pas. Ce teste tous les index pour voir si c'est compatible avec le fait d'être un tableau.
OriginalL'auteur Houshalter