Wie weiß ich, ob eine Tabelle ist ein array?
Entwickle ich eine einfache optimierte JSON Funktion. Lua verwendet Tabellen darstellen arrays aber im JSON-Format, die ich brauche, um zu erkennen, zwischen Ihnen. Der folgende code verwendet wird:
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))
Können Sie im JSON-Referenz auf eine object
ist, was man eine table
im Lua und es unterscheidet sich von einem array
.
Die Frage ist, wie kann ich erkennen, wenn eine Tabelle verwendet wird, wie ein array?
- Eine Lösung ist natürlich, gehen Sie durch alle Paare und sehen, wenn Sie nur aufeinander folgende numerische Tasten, aber das ist nicht schnell genug.
- Eine andere Lösung ist das setzen einer flag in der Tabelle, die sagt, es ist ein array kein Objekt.
Einfacher/intelligentere Lösung?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie wollen schnelle, einfache, nicht-intrusive Lösung, die die Arbeit meisten der Zeit, dann würde ich sagen, nur check index 1 - falls vorhanden, die Tabelle ist ein array. Sicher, es gibt keine Garantie, aber in meiner Erfahrung, Tabellen nur selten haben beide numerischen und anderen Tasten. Ob es ist akzeptabel für Sie, um Fehler, einige Objekte für arrays und ob Sie erwarten, dass dies geschehen wird, hängt oft von Ihrem Szenario für den Einsatz - ich denke, es ist nicht gut für die Allgemeine JSON-Bibliothek.
Edit: Für die Wissenschaft, ich ging, um zu sehen, wie Lua CJSON tut Dinge. Es geht durch alle Paare, und überprüft, ob alle Schlüssel sind ganze zahlen, während die maximale-Taste (die entsprechende Funktion ist
lua_array_length
). Dann entscheidet es sich, ob serialisieren, die die Tabelle als array oder Objekt, je nachdem, wie spärlich die Tabelle ist (das Verhältnis wird vom Benutzer gesteuert), d.h. eine Tabelle mit Indizes 1,2,5,10 wird wahrscheinlich serialisiert ein array, während eine Tabelle mit Indizes 1,2,1000000 wird als ein Objekt. Ich denke, dies ist eigentlich eine ganz gute Lösung.Nein es gibt keine integrierte Möglichkeit zu differenzieren, da in Lua gibt es keinen Unterschied.
Gibt es bereits bestehende JSON-Bibliotheken, die wohl schon die dies tun (zB. Lua CJSON.
Andere Optionen sind
__newindex
so, dass nur neue und die anschließende numerische Indizes verwendet werden dürfen.@AlexStack
Dieser code ist falsch, wenn schlägt fehl, wenn eine der Einbauteile ist
false
.Ich denke, der ganze Ausdruck kann geändert werden, um
type(t[i]) == nil
aber es will immer noch nicht in einige der Szenarien, da wird es keine Unterstützung für null-Werte.Einen guten Weg zu gehen, denke ich, versucht mit
ipairs
oder überprüfen, ob#t
gleichcount
, aber#t
gibt 0 zurück, mit Objekten undcount
null mit leeren arrays, so müssen Sie möglicherweise eine zusätzliche überprüfung an den Anfang der Funktion, so etwas wie:if not next(t) then return true
.Nebenbei, ich bin einfügen eine andere Implementierung gefunden, die in lua-cjson (von Mark Pulford):
Den einfachsten Algorithmus zur Unterscheidung zwischen arrays und nicht-arrays ist diese:
Erklärung hier: https://web.archive.org/web/20140227143701/http://ericjmritz.name/2014/02/26/lua-is_array/
Sagte, Sie habe noch Probleme mit leeren Tabellen - Sie sind "arrays" oder "hashes"?
Für den besonderen Fall der Serialisierung von json, was ich Tue, ist die Kennzeichnung von arrays mit einem Feld in Ihre metatable.
Hier ist mehr einfachste Prüfung auf Grundlage der Lua-spezifische #len-Funktion-Mechanismus.
function is_array(tbl) return type(tbl) == 'table' and (#tbl > 0 or next(tbl) == nil) end
.Dank. Ich entwickelte den folgenden code und es funktioniert:
Schrieb ich diese Funktion für ziemlich Druck lua-Tabellen, und hatte dasselbe problem zu lösen. Keine der Lösungen hier Konto für Grenzfälle wie einige Tasten werden zahlen, andere aber nicht. Diese tests jeden index zu sehen, ob es kompatibel mit einem array.