Why lua json decode make all number key as string? SOLVED

Is it possible to fix it somehow? very inconvenient to constantly convert :hot_face:

and pprint() not show type of key and value

all about table

Not sure I understand. Can you share an example?

The key in an object must be a string. If you want to not have strings then you must use sequential integer keys starting from 0, which will result in an array instead.

array(2) {
  [1]=>
  array(2) {
    ["p"]=>
    int(4)
    ["r"]=>
    string(1) "r"
  }
  [3]=>
  array(2) {
    ["p"]=>
    int(7)
    ["r"]=>
    string(1) "l"
  }
}
string(41) "{"1":{"p":4,"r":"r"},"3":{"p":7,"r":"l"}}"

this send my server. key 1 and 3 is string (((

in defold i get

{ --[[00000000028C5040]]
  1 = { --[[00000000028E4BF0]]
    r = "r",
    p = 5
  },
  3 = { --[[00000000028E4CB0]]
    r = "l",
    p = 6
  }
}

but 1 and 3 is string :sleepy:
and i cant compare with integer variable - only use with tostring(variable)
it’s not a problem - it’s just inconvenient

function func.convert_table_string_key_to_number(table, subkey) -- from string key to number
	local t2 = {}

	if subkey ~= false then
		for key, val in pairs(table[subkey]) do
			t2[tonumber(key)] = val
		end

		table[subkey] = t2
	else
		for key, val in pairs(table) do
			t2[tonumber(key)] = val
		end

		table = t2
	end
	
	return table
end

json.decode() doesn’t convert to Json format, it converts to Lua tabler format. Since the json.decode() is designed to handle content from json.encode() this conversion makes sense.

If you want your own decode, your solution is one way to do it.
Another is to stick to using actual strings as keys, i.e. strings that cannot be converted to integers.

Thank you for your reply. I already understood

Well, if you are sending string representations of numbers then there is no way for json.decode() to know that you want those strings converted to numbers.

json.decode() converts to the corresponding Lua type, in this case a json string gets converted into a Lua string, which makes sense.

It turned out that this is a problem of the json standard itself.

its internal keys are string only

1 Like

Hello! I faced same problem.
Yeah json does not support non-string keys and it is ok. But I need to save table as json array. Is there any way to do it?

For example my server expects list of something. Or I need to store some big matrix with in indexies

So you have a Lua table and you need to encode this to a json array? Why wouldn’t json.encode() work in this case?

	local t = { "a", "b", "c", "d" }
	local j = json.encode(t)
	print(j) -- ["a","b","c","d"]

I construct the array/table dynamicly like that

local M = {}
M.data = {}
M.data.tiles = {}
M.data.chunk = {x = 0, y = 0}
M.data.width = 0
M.data.height = 0

function M:init(x, y, width, height)
	self.data.width = width
	self.data.height = height
	
	for i=0, width do
		-- self.data.tiles[i] = {}
		table.insert(self.data.tiles, {})
		
		for j=0, height do
			--self.data.tiles[i][j] = 0		
			table.insert(self.data.tiles[j], 0)
		end
	end
	
	return M
end

and in this case json.encode(t) saves table.

I got it. You need to add indexies from 1 and than json will convert it to array. I had zero index and it was converted to table

1 Like