Anomalía de la biblioteca Corona SDK json

Hola a todos Para nadie es un secreto que usar json en sus proyectos en Corona SDK puede hacer que algunas cosas sean bastante convenientes. Encontré una anomalía interesante al trabajar con la biblioteca, que la práctica ha demostrado que no es en absoluto un error, sino más bien una característica que debe conocer y estar preparado. Consideremos todo en detalle.

1. Descripción del problema.


Supongamos que tenemos una matriz Lua que se ve así:

ar = {23,45,56,'weer'} 

Si tiene todo lo normal con una comprensión del idioma, esta matriz se le presenta como se muestra a continuación, solo baja en grasa debido a las circunstancias - TAN POSIBLE:

 ar = {[1] = 23,[2] = 45,[3] = 56,[4] = 'weer'} 

Si decide convertir esta matriz a json, la salida le dará algo como esto (por supuesto, no olvidaremos conectar la biblioteca json):

 ar = {[1] = 23,[2] = 45,[3] = 56,[4] = 'weer'} json = require "json" local str = json.encode(ar) print(str)--> [23,45,56,"weer"] 

Como puede ver, json también sabe acerca de la existencia de este tipo de registro simplificado, en el que si los elementos de la matriz van secuencialmente, no se numerarán explícitamente, y esto es maravilloso ya que a menudo usamos json en nuestros proyectos para el protocolo de red o para guardar en un archivo, y el tamaño extra es completamente inexistente a que

Ahora intentemos convertir el drenaje de nuevo en una tabla Lua y mostrar su contenido, prestando atención a los tipos de datos de las claves:

 local str = '[23,45,56,"weer"]' local ar2 = json.decode(str) for k,v in pairs(ar2)do print(k,type(k),v) end --[[ 1 number 23 2 number 45 3 number 56 4 number weer ]] 

Como puede ver, el resultado es más de lo esperado, la tabla ar en la entrada corresponde totalmente a la tabla ar2 en la salida. Ahora, siguiendo los 2 puntos anteriores, pero al mismo tiempo habrá una matriz en la que hay una secuencia interrumpida en la matriz, digamos que agregamos la clave 6 (sin pasar por 5) con el valor 'wtf'. Estamos rompiendo

 json = require "json" ar = {23,45,56,'weer',[6] = 'wtf'} local str = json.encode(ar) print(str)-->[23,45,56,"weer",null,"wtf"] local t = json.decode(str) for k,v in pairs(t)do print(k,type(k),v) end --[[ 1 number 23 2 number 45 3 number 56 4 number weer 6 number wtf ]] 

Como puede ver, todo salió bien nuevamente, ya que json.encode esperaba esta captura y, en lugar de una clave nula insertada 5 inexistente y todo esto terminó con éxito, no nos detendremos allí y agregaremos otra clave 777 con un valor de 1 a la matriz, lo más probable es que esperemos que la tabla se convierte de la misma manera e incluirá 770 nulo; esta no es la mejor opción, ya que ocupará mucho más espacio, pero simplemente no hay otra forma en json para crear un análogo completo de esta tabla lua ya que la clave no está en json puede ser claramente vlen como un número. Nos fijamos en lo que pasó.

 json = require "json" ar = {23,45,56,'weer',[6] = 'wtf',[777] = 1} local str = json.encode(ar) print(str)-->{"1":23,"2":45,"3":56,"4":"weer","6":"wtf","777":1} local t = json.decode(str) for k,v in pairs(t)do print(k,type(k),v) end --[[ 1 string 23 777 string 1 3 string 56 2 string 45 4 string weer 6 string wtf ]] 

Como puede ver, el codificador fue al revés y convirtió todas las claves con el número de tipo de valor a cadena. No es ningún secreto que una función de este tipo puede generar errores (si no lo sabe), o muletas que usan transformaciones explícitas de número / cuerda al trabajar con esta tabla, en cualquier caso, esto no será muy placentero. Considera cómo lidiar con esto.

2. resolver el problema


Para resolver este problema, puede escribir una función que inicializará todas las matrices en las que surgió el problema, luego en el código tendrá que recordar constantemente este problema y aplicar esta función en todas partes, esta es una forma normal, pero no la mejor, y por lo tanto, existe el plan B Redefina la implementación de la función json.decode para que todas las áreas problemáticas se conviertan automáticamente y esta solución funcione tanto en el primer anidamiento en la matriz pasada como en los archivos adjuntos más profundos. Realizaremos la redefinición del valor de la función justo después de conectar la biblioteca json al proyecto. La siguiente implementación está disponible:

 json = require "json" local jd = json.decode--   local norm_ar json.decode = function(ar,not_convert)--  local res = jd(ar) --     --    norm_ar = function(root) local res = {} --  for k,v in pairs(root)do res[k] = v end --   for k,v in pairs(res) do if type(k) == 'string' and--  string.match(tostring(k),'%D') == nil then--    -- string -> number root[tonumber(k)] = root[k] root[k] = nil--   end --      if type(v) == 'table' then norm_ar(v) end end return root end --   not_convert    return not_convert and res or norm_ar(res) end 

Ahora intente realizar la operación anterior nuevamente:

 ar = {23,45,56,'weer',[6] = 'wtf',[777] = 1} local str = json.encode(ar) print(str)-->{"1":23,"2":45,"3":56,"4":"weer","6":"wtf","777":1} local t = json.decode(str) for k,v in pairs(t)do print(k,type(k),v) end --[[ 1 number 23 2 number 45 3 number 56 4 number weer 6 number wtf 777 number 1 --]] 

Como puede ver, todo funcionó y la matriz retuvo su estructura anterior. Por último, quiero agregar que si por alguna razón necesita evitar esta conversión, la nueva opción de implementación json.decode admite un segundo parámetro opcional que deshabilitará la conversión.

¡Adiós a todos!

Source: https://habr.com/ru/post/es422591/


All Articles