Lua:lua-cjson:Cannot serialise table: excessively sparse array

Lua:lua-cjson:Cannot serialise table: excessively sparse array

Code:

local cjson = require "cjson"
local cjson2 = cjson.new()
local array = {}
array[19] = 19
cjson2.encode(array)

执行时异常:

Cannot serialise table: excessively sparse array

查阅 cjson.encode API 手册:

在编码 Json 数组时,lua-cjson 按照缺失的数值数目将 Lua table 分为三类:

1)标准型(Normal)

例如:

local array = {}
array[1] = 1
array[2] = 2
array[3] = 3

数组大小是3,数组第1、2、3个元素都存在。

2)稀疏型(Sparse)

例如:

local array = {}
array[1] = 1
array[2] = 2
array[9] = 9

数组长度是9,但除了第1、2、9个元素存在外,其余的元素都不存在(缺失6个元素),都为 null 值。

只要有一个元素缺失,就是稀疏型。(At least 1 value is missing.)

3)过度稀疏型(Excessively sparse)

例如:

local array = {}
array[19] = 19

数组长度是19,但是只有1个元素存在,缺失18个元素。

如何判断稀疏型和过度稀疏型界限呢?

An array is excessively sparse when all the following conditions are met:

ratio > 0

maximum_index > safe

maximum_index > item_count * ratio

先暂时不管 “ratio” 是啥,先看一个 API:

convert, ratio, safe = cjson.encode_sparse_array([convert[, ratio[, safe]]])
-- "convert" must be a boolean. Default: false.
-- "ratio" must be a positive integer. Default: 2.
-- "safe" must be a positive integer. Default: 10.

默认情况下,ratio 值为2,并且 convert 是 false。

查看源码:

Step 1:

执行 cjson.new 创建 cjson 实例对象时,会创建一个独立的默认参数配置信息到 cjson 实例对象中。

Step 2:

json_create_config 中创建了一个完全用户数据(内存)对象(默认参数配置表),并初始化其默认配置。

Step 3:

可以看到,默认配置:convert=false(0);ratio=2;safe=10。


回到原点,看看我们的 lua 脚本在编码时为何报错?

Lua table (array) 大小是 19,但是其中只有一个元素,缺失 18 个元素。

默认情况,ratio 是 2,maximum_index 是 19,item_count 是 1。

已经满足一下条件:

ratio2) > 0

maximum_index19) > safe10maximum_index19) > item_count(1) * ratio(2

此 Lua table 属于过度稀疏型数组。

对于过度稀疏型数组在编码 Json 时将出异常报错。

By default, attempting to encode an excessively sparse array will generate an error.

于是执行 cjson.encode 时报错。

我们可以尝试从 lua-cjson 源码中查找报错字符串来定位错误位置:

查阅 lua_cjson.c 源码:

此处代码逻辑已经很清晰啦,就是我们上面 API 中描述的异常时的条件。

我们可以通过调用 encode_sparse_array 此 API 来设置一个 cjson 实例对象的参数配置,改变 ratio、convert、safe 的值。

由于我们仅仅是希望将 Lua table = {[19]=19} 可以正常地转换为 Json 字符串,所以仅需改变 convert 配置值即可。

If convert is set to true, excessively sparse arrays will be converted to a JSON object.

示例:

Code:

local cjson = require "cjson"
local cjson2 = cjson.new()
cjson2.encode_sparse_array(true)

local array1 = {}
array1[6] = 6
print(cjson2.encode(array1))

local array2 = {}
array2[19] = 19
print(cjson2.encode(array2))

执行结果:

最后,lua-cjson 的 encode 将过度稀疏型数组转换成了一个 Json 对象,而非是 Json 数组。


思考:

如果将 Lua table = {[19]=19} 转换为 Json 数组应该怎么做?

Lua 脚本:

local cjson = require "cjson"
local cjson2 = cjson.new()

cjson2.encode_sparse_array(false, 100)

local array2 = {}
array2[19] = 19
print(cjson2.encode(array2))

执行结果:

^_^

参考文档:

1.https://www.kyne.com.au/~mark/software/lua-cjson-manual.html#encode_sparse_array

猜你喜欢

转载自blog.csdn.net/test1280/article/details/81275735
今日推荐