-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow to customize internal object creator to allow keeping native order during decode #4
base: master
Are you sure you want to change the base?
Conversation
My apologize for the very late reply! I agree there should be a way to keep the order of objects. If you agree, I'd like to include your test sample to the source tree and add the option, and merge it soon. |
I realise this ticket is two years old at this point, but I had some thoughts. The specific goal of retaining key order can be achieved with a relatively small change: diff --git a/decoder.lua b/decoder.lua
index 4478894..2e40aed 100644
--- a/decoder.lua
+++ b/decoder.lua
@@ -403,10 +403,12 @@ local function newdecoder()
if rec_depth > 1000 then
decode_error('too deeply nested json (> 1000)')
end
- local obj = {}
+ local obj = {[0]=false} -- distinguish empty arrays from objects
f, pos = find(json, '^[ \n\r\t]*', pos)
pos = pos+1
+
+ local i = 0
if byte(json, pos) ~= 0x7D then -- check closing bracket '}' which means the object empty
local newpos = pos-1
@@ -441,7 +443,8 @@ local function newdecoder()
f = dispatcher[byte(json, newpos+1)]
end
pos = newpos+2
- obj[key] = f() -- parse value
+ i = i+2
+ obj[i-1], obj[i] = key, f() -- parse value
f, newpos = find(json, '^[ \n\r\t]*,[ \n\r\t]*', pos)
until not newpos
@@ -452,6 +455,12 @@ local function newdecoder()
pos = newpos
end
+ -- Second pass for kv mapping is empirically faster than doing it
+ -- alongside the pair assignments in the inner loop
+ for j=1,i,2 do
+ obj[obj[j]] = obj[j+1]
+ end
+
pos = pos+1
rec_depth = rec_depth - 1
return obj Based on informal testing, this imposes a 10~20% performance penalty. There are a few issues to consider, however:
|
Hello guys, I think the ability to remind the keys order is a good feature, but it is only usefull in particular case. Lua still have lot of different interpretor version, lua 5.1/5.2/5.3, luajit, raptorjit, etc. I think lunajson can not provide a way to get the ordered-keys without providing the Finaly I still think that adding an external handler is not a bad choice.
If we want make the user's life easier we can add the handler and pairs implementation. If you really refuse external handling (I can understand that), is it possible to add an argument to toggle this feature ? |
@muhmuhten I use your patch and add some |
Hello, I made some changes. Only Lua >= 5.2 take care about the We should support to re-encode in the same readed order (not tested yet). Regards, |
Hello,
A lua simple hash table does not remind the original order.
The only way to remind the write order is to setup a special metatable.
I didn't try to implement this feature directly inside lunajson because I think it is not always usefull.
I made a way to customized it with an external handler.
My test sample with writeorder.lua has a stable result :
Regards,