Lua 中嵌套数组的行为

Behavior of nested arrays in Lua

我有这段代码:

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 ? 

来自dkjson documentation:

It can also be used to save Lua data structures, but you should be aware that not every Lua table can be represented by the JSON standard. For example tables that contain both string keys and an array part cannot be exactly represented by JSON.

addEntry("toto", 28000, 11111)

打印

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

您创建并编码了 table

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

这给你 json 字符串

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

当你解码这个 json 字符串时你会得到一个 lua table 像

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

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

所以当你打电话时

addEntry("toto", 28000, 22222)

小时又是一个数字,你最终会得到 table

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

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

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

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

现在我们再次解码,留下 table

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

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

现在您接下来的每个调用都会发生同样的事情。您添加一个数字键并在 en/decoding 过程中将其丢失。

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

双重值是由于您这样做造成的

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

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

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