Lua中嵌套数组的行为

时间:2021-01-06 01:03:30

标签: lua lua-table

我有这段代码:

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

function addEntry(position, hour, id)

        local data = json.decode(dataStr) or {} 
        
        if not data.detections then
            print("create 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 上有这个输出:

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

I would have expected to have this in the final string : 

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

Can somebody explain to me this Lua behavior ? The override instead of adding a new value, and this remaining separate first value ? 

1 个答案:

答案 0 :(得分:2)

来自dkjson documentation

<块引用>

它也可以用来保存Lua数据结构,但是你应该 意识到并非每个 Lua 表都可以用 JSON 表示 标准。例如包含字符串键和一个 数组部分不能用 JSON 精确表示。

addEntry("toto", 28000, 11111)

印刷品

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

您创建并编码了表格

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

哪个给你 json 字符串

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

当你解码这个 json 字符串时,你会得到一个类似 lua 的表

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

正如你在解码后看到的 28000 现在是一个字符串键,而不是你编码的整数。

所以当你打电话

addEntry("toto", 28000, 22222)

在这里,小时又是一个数字,你会得到表格

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

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

如果你再次编码,你会得到 json 字符串

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

现在我们再次解码,留下表格

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

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

现在,您接下来的每个电话都会发生同样的事情。您添加了一个数字键并在编码/解码过程中丢失了它。

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

双倍值是由于您这样做

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

data.detections[position][hour]nil 时,由于上述问题,在每次调用中都是如此。

当您在表中添加 id 之后,您最终会得到一个包含 id 两次的表。而是创建一个空表。