json.lua icon indicating copy to clipboard operation
json.lua copied to clipboard

一个json字符串,decode成table,之后再把这个table encode成json,俩个json不一样!

Open flyerSon opened this issue 5 years ago • 5 comments

local json_before = {"key":[{},{},{},{},{},{},{},{},{},{}],"roleAttr":{"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"0":0,"1":0,"2":0}} local list = json.decode(json_before ); local json_after = json.encode(list); 此时的json_afre为:{"key":[[],[],[],[],[],[],[],[],[],[]],"roleAttr":{"1":0,"0":0,"3":0,"2":0,"5":0,"4":0,"7":0,"6":0,"9":0,"8":0}}

为何不一样?

flyerSon avatar Jun 15 '19 09:06 flyerSon

目测是源码encode_table的next测到nil直接判定为array了 可以小魔改一下,比如:

 local t_type = 'array'
 local n = 0
 local max = -1
 for k in pairs(val) do
    if type(k) == "string" then
      t_type = 'object'
      break
    elseif type(k) == "number" then
      n = n + 1
      max = math.max(max, k)
    else
      error("invalid table: mixed or invalid key types")
    end
  end
if t_type == 'array' then
    if n == 0 then
      t_type = 'object'
    elseif n ~= #val then
      t_type = 'sparse_array'
    end
  end

来区分array、稀疏array跟object

utmhikari avatar Jul 29 '19 09:07 utmhikari

English please.

Trumeet avatar Oct 05 '19 22:10 Trumeet

(Just translating)

local json_before = {"key":[{},{},{},{},{},{},{},{},{},{}],"roleAttr":{"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"0":0,"1":0,"2":0}} local list = json.decode(json_before ); local json_after = json.encode(list); 此时的json_afre为:{"key":[[],[],[],[],[],[],[],[],[],[]],"roleAttr":{"1":0,"0":0,"3":0,"2":0,"5":0,"4":0,"7":0,"6":0,"9":0,"8":0}}

为何不一样?

local json_before = {"key":[{},{},{},{},{},{},{},{},{},{}],"roleAttr":{"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"0":0,"1":0,"2":0}} local list = json.decode(json_before ); local json_after = json.encode(list); In this moment json_after is : {"key":[[],[],[],[],[],[],[],[],[],[]],"roleAttr":{"1":0,"0":0,"3":0,"2":0,"5":0,"4":0,"7":0,"6":0,"9":0,"8":0}}

Why are json_before and json_after different?

目测是源码encode_table的next测到nil直接判定为array了 可以小魔改一下,比如:

 local t_type = 'array'
 local n = 0
 local max = -1
 for k in pairs(val) do
    if type(k) == "string" then
      t_type = 'object'
      break
    elseif type(k) == "number" then
      n = n + 1
      max = math.max(max, k)
    else
      error("invalid table: mixed or invalid key types")
    end
  end
if t_type == 'array' then
    if n == 0 then
      t_type = 'object'
    elseif n ~= #val then
      t_type = 'sparse_array'
    end
  end

来区分array、稀疏array跟object

It seems like the encode_table treat input table as array when it found nil by next. Could modify code like...

 local t_type = 'array'
 local n = 0
 local max = -1
 for k in pairs(val) do
    if type(k) == "string" then
      t_type = 'object'
      break
    elseif type(k) == "number" then
      n = n + 1
      max = math.max(max, k)
    else
      error("invalid table: mixed or invalid key types")
    end
  end
if t_type == 'array' then
    if n == 0 then
      t_type = 'object'
    elseif n ~= #val then
      t_type = 'sparse_array'
    end
  end

...to distinguish between array, sparse array and table.

fnaith avatar Jun 01 '20 02:06 fnaith

local __json_object = {__json_object =  function() end}
function json.newObject()
  return setmetatable({}, __json_object)
end

parse_object

local function parse_object(str, i)
  local res = json.newObject()

encode_table

  local t = getmetatable(val)
  if (t == nil or t.__json_object == nil) and (rawget(val, 1) ~= nil or next(val) == nil) then

ruyi789 avatar Nov 22 '22 19:11 ruyi789

Hello! Would you mind creating a pull request on my fork so that I may include your suggestions?

Thanks!

alexandro-rezakhani avatar Nov 22 '22 20:11 alexandro-rezakhani