我在文本数据库字段中具有以下形式的json编码图表配置:
{"Name":[[1,1],[1,2],[2,1]],"Name2":[[3,2]]}
这些ID的第一个数字是另一个表的主键。我想在删除行时使用触发器删除那些条目,一个plperl函数会很好,除非它不保留哈希的顺序,并且该顺序在该项目中很重要。我该怎么办(不更改json编码配置的格式)?注意:图表名称可以包含任何字符,因此使用正则表达式很难做到这一点。
答案 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::Reader
或JSON::SL
。