Hello. Few people will have a secret that using json in your projects on the Corona SDK can make some things quite comfortable. I discovered one interesting anomaly when working with the library, which, as practice has shown, is not at all a mistake, but rather a feature about which you should know and be ready for it. Consider all the details.
1. Description of the problem
Suppose we have a Lua array of the following form:
ar = {23,45,56,'weer'}
If everything is normal with your understanding of the language, this array appears to you as shown below, simply degreased due to the circumstances - it is possible:
')
ar = {[1] = 23,[2] = 45,[3] = 56,[4] = 'weer'}
If you decide to convert this array to json, then at the output you will get something like this (of course, we will not forget to connect the json library):
ar = {[1] = 23,[2] = 45,[3] = 56,[4] = 'weer'} json = require "json" local str = json.encode(ar) print(str)
As you can see, json also knows about the existence of this kind of simplified notation in which if the elements of the array go sequentially, they will not be explicitly numbered, which is great since json is not uncommonly used in our projects for the network protocol or saving to the file and the extra size is completely for what.
Now we will try to convert the drain back to Lua table and display its contents while paying attention to the data types of the keys:
local str = '[23,45,56,"weer"]' local ar2 = json.decode(str) for k,v in pairs(ar2)do print(k,type(k),v) end
As you can see, the result was more than expected, the table ar at the input fully corresponds to the table ar2 at the output. Now, following the previous 2 points, but the input will be an array in which there is an interrupted sequence in the array, let's say we add key 6 (bypassing 5) with the value 'wtf'. We are criminal.
json = require "json" ar = {23,45,56,'weer',[6] = 'wtf'} local str = json.encode(ar) print(str)
As you can see, everything turned out remarkably well as json.encode expected this trick and instead of the nonexistent 5 key inserted null and so everything ended in success, we will not stop and add another 777 key to the array with a value of 1, most likely we expect that the table is converted in the same way and will include 770 null - this is certainly not the best option since it will take much more space, but there is no other way in json that would create a complete analog of this lua table since in json the key is not maybe clearly as a number. We look what happened.
json = require "json" ar = {23,45,56,'weer',[6] = 'wtf',[777] = 1} local str = json.encode(ar) print(str)
As you can see, the encoder went the other way and converted all the keys with the value type number to string. It’s no secret that such a feature can and will lead to errors (if you don’t know about it), or to crutches with the use of explicit tonumber / tostring transformations when working with this table, in any case it will not bring much pleasure. Consider how to deal with this.
2. Problem solving
In order to solve this problem, you can write a function that will convert all the arrays in which the problem arose to the initial state, then you will have to constantly remember this problem in the code and apply this function everywhere, this is a normal way, but not the best, and therefore there is a plan B We will override the implementation of the json.decode function so that all problem areas are automatically converted and this solution works both on the first nesting in the transferred array and on deeper investments. We will do the redefinition of the function's value immediately after we connect the json library to the project. There is the following implementation:
json = require "json" local jd = json.decode
Now let's try to perform the previous operation again:
ar = {23,45,56,'weer',[6] = 'wtf',[777] = 1} local str = json.encode(ar) print(str)
As you can see, everything worked and the array retained its former structure. Lastly, I want to add that if for some reason you need to avoid this conversion, a new implementation option json.decode supports the second optional parameter that disables the conversion.
Bye everyone!