Lua 中嵌套数组的行为

我有这样一段代码:

json = require('dkjson')
dataStr = "{}"

function addEntry(position, hour, id)

        local data = json.decode(dataStr) or {}

        if not data.detections then
            print("创建 data.detections")
            data.detections = {}
        end
        if not data.detections[position] then
            print("data.detections[position]")
            data.detections[position] = {}
        end
        if not data.detections[position][hour] then
            print("data.detections[position][hour]")
            data.detections[position][hour] = {}
        end
        table.insert(data.detections[position][hour], id)

        dataStr = json.encode(data)
        print(dataStr)
end

addEntry("toto", 28000, 11111)
addEntry("toto", 28000, 22222)
addEntry("toto", 28000, 33333)
addEntry("toto", 28000, 44444)
addEntry("toto", 28000, 55555)

我在 Zerobrane 上得到了以下输出:

创建 data.detections
创建 data.detections[position]
创建 data.detections[position][hour]
{"detections":{"toto":{"28000":[11111,11111]}}}
创建 data.detections[position][hour]
{"detections":{"toto":{"28000":[22222,22222],"28000":[11111,11111]}}}
创建 data.detections[position][hour]
{"detections":{"toto":{"28000":[33333,33333],"28000":[11111,11111]}}}
创建 data.detections[position][hour]
{"detections":{"toto":{"28000":[44444,44444],"28000":[11111,11111]}}}
创建 data.detections[position][hour]
{"detections":{"toto":{"28000":[55555,55555],"28000":[11111,11111]}}}

我希望最终字符串是这样的:

```{"detections":{"toto":{"28000":[11111,22222,33333,44444,55555]}}}

有人能解释一下这是 Lua 的行为吗?覆盖而不是添加新值,而这仍然是分开的第一个值吗?
点赞
用户2858170
用户2858170

从[dkjson文档](http://dkolf.de/src/dkjson-lua.fsl/home)中可以得知:

它也可用于保存Lua数据结构,但您应该意识到,并非每个Lua.table都可以由JSON标准表示。例如,同时包含字符串键和数组部分的表不能由JSON精确表示。

addEntry(“ toto”,28000,11111)

输出:

create data.detections
create data.detections[position]
create data.detections[position][hour]
{"detections":{"toto":{"28000":[11111,11111]}}}

你创建并编码了 表

{探测 ={toto = {[28000] = {11111,11111}}}}

这给你json字符串

'{"检测":{"toto":{"28000":[11111,11111]}}}'

当您解码此json字符串时,将得到一个lua表,如下所示。

{detections = {toto = {["28000"] = {11111, 11111}}}}

如您所见,解码后,28000 现在是字符串键,不是编码时的整数。

因此,当您调用

addEntry(“ toto”,28000,22222)

其中hour再次是一个数字,您将得到表

{探测 ={toto = {[28000] = {2222222222},["28000"] = {1111111111}}}}

其中包含数字和字符串键的值。

如果再次进行编码,您将得到json字符串

'{"detections":{"toto":{"28000":[22222,22222],"28000":[11111,11111]}}}'

现在我们再次解码,表将变为

{检测 ={toto = {[“ 28000”] = {11111,11111}}}}

因为第一个“28000”条目{22222,22222}当然被第二个{11111,11111}覆盖,因为我们不能有两个相同键的元素。

现在对于您的每个以下调用,将发生相同的情况。您添加数字键,并在en/decoding过程中丢失它。

仅当您的表是1到n的连续整数键的序列时,才使用数字键。所有其他表键都转换为字符串。

双值是由于您这样做的原因

 data.detections[position][hour] = {id}

data.detections[position][hour]nil时,由于上述问题,这在每个调用中都是真的。

由于在之后将id添加到表中,因此最终得到包含id两次的表。请改为创建一个空表。

2021-01-06 06:54:17