perl解码和编码json保留顺序

时间:2018-07-16 16:58:25

标签: json perl hash

我在文本数据库字段中具有以下形式的json编码图表配置:

{"Name":[[1,1],[1,2],[2,1]],"Name2":[[3,2]]}

这些ID的第一个数字是另一个表的主键。我想在删除行时使用触发器删除那些条目,一个plperl函数会很好,除非它不保留哈希的顺序,并且该顺序在该项目中很重要。我该怎么办(不更改json编码配置的格式)?注意:图表名称可以包含任何字符,因此使用正则表达式很难做到这一点。

4 个答案:

答案 0 :(得分:1)

JSON对象是无序的。您将必须以某种方式将所需的顺序编码到数据中

{"Name":[[1,1],[1,2],[2,1]],"Name2":[[3,2]], "__order__":["Name","Name2"]}

[{"Name":[[1,1],[1,2],[2,1]]},{"Name2":[[3,2]]}]

答案 1 :(得分:1)

好吧,我设法解决了我的问题,但这不是一般性的解决方案,因此可能对临时读者没有帮助。无论如何,我借助于数据库获得了键的顺序,我这样调用了函数:

SELECT remove_from_chart(
    chart_config,
    array(select * from json_object_keys(chart_config::json)),
    id);

然后我按照第二个参数的顺序浏览了各个键,并将结果放入一个新的绑定(IxHash)哈希中,并对其进行了json编码。

很可悲的是,当我使用的其他所有功能(至少在此项目上)都完成(php,postgres,firefox,chrome)时,没有perl json解码器可以保留键顺序。

答案 2 :(得分:1)

您需要使用流式JSON解码器,例如JSON::Streaming::Reader。然后,您可以将JSON存储为键/值对的数组,而不是哈希。

如何使用它的实际实现高度依赖于数据的结构,但是给出了简单的示例……这是一个简单的实现。

use strict;
use warnings;
use JSON::Streaming::Reader;
use JSON 'to_json';

my $s = '{"Name":[[1,1],[1,2],[2,1]],"Name2":[[3,2]]}';

my $jsonr = JSON::Streaming::Reader->for_string($s);

my @data;
while (my $token = $jsonr->get_token) {
    my ($key, $value) = @$token;
    if ($key eq 'start_property') {
        push @data, { $value => $jsonr->slurp };
    }   
}   

print to_json(\@data);

此脚本的输出始终为:-

[{"Name":[[1,1],[1,2],[2,1]]},{"Name2":[[3,2]]}]

答案 3 :(得分:0)

可能是您想要JSON数据的流式解码器,例如SAX解析器。如果是这样,请参阅JSON::Streaming::ReaderJSON::SL