【问题标题】:perl: how to sort a JSON structure on something other than "root" key attributesperl:如何根据“根”键属性以外的东西对 JSON 结构进行排序
【发布时间】:2011-04-01 17:12:30
【问题描述】:

Perl: 如何使用 JSON::PP 对复杂结构进行排序?

来自 JSON 文档:

由于排序例程在 JSON::PP 范围,给定的子例程 名称和特殊变量 $a, $b 将开始'JSON::PP::'。

这是我的尝试,似乎不起作用

open my $fh, ">", $file or warn " exportAsJSON: can't open file: '$file': $!";
print $fh  $coder->sort_by(sub {$_->{column_def}->{$JSON::PP::a} cmp $_->{column_def}->{$JSON::PP::b}  } )->encode(\%json);
close $fh;

我想按键排序,然后是“column_def”下面的属性键上的column_def属性,即 密度,depth_in_m,mag_sus :

{
    "column_def":
        {
            "depth_in_m":
                {
                    "names":"depth_in_m",
                    "pos":"0"
                },
            "mag_sus":
                {
                    "names":
                        {
                            "A_ALIAS":"Mag-Sus.",
                            "A_DESC":"magnetic susceptibility in SI",
                            "ATTRIBUTE":"MAG_SUS"
                        },
                    "pos":"2"
                },
            "density":
                {
                    "names":
                        {
                            "A_ALIAS":"Density",
                            "A_DESC":"density in gm\/cc",
                            "ATTRIBUTE":"DENSITY"
                        },
                    "pos":"1"
                }
        },
    "data":
        {
            "depth_in_m":"14.635",
            "mag_sus":"n.a.",
            "density":"n.a."
        }
}

【问题讨论】:

  • 我很想知道您为什么要对将解析为哈希的东西进行排序 - 它没有固有的顺序。
  • @Bears 会吃掉你:确实,内存中的表示没有内在的顺序。我想将排序后的哈希结构保存到文件(或临时文件)中,以进行差异和视觉检查(以及之后更复杂的事情)。

标签: perl json sorting


【解决方案1】:

我不确定我是否了解您希望如何对 JSON 输出进行排序——除了按哈希键排序。如果这就是你想要的,只需将 canonical 方法传递一个 true 参数即可。

use strict;
use warnings;

use JSON::PP;

# A simple hash-of-hashes for exploration.
my $h = {
    Z => { c => 1, d => 2 },
    A => { a => 3, r => 4 },
    B => { c => 5, x => 6 },
    S => { q => 7, d => 8 },
};

my $js = JSON::PP->new;
$js->canonical(1);

my $output = $js->encode($h);
print $output;

如果您确实使用了sort_by 方法,那么在sort 块中使用$_ 是没有意义的:它代表什么?从文档中不清楚sort_by 代码将收到哪些参数。像这样使用Data::Dumper

use Data::Dumper qw(Dumper);

my $sorter = sub {
    # See what's going on.
    print "$JSON::PP::a cmp $JSON::PP::b\n";
    print Dumper(\@_, $_);
    <STDIN>;

    # Sort hash keys alphabetically.
    $JSON::PP::a cmp $JSON::PP::b;
};

my $output = $js->sort_by($sorter)->encode($h);

您可以推断sort_by 的工作方式如下: (1) 它接收两个参数,JSON::PP 对象和当前正在使用的哈希引用; (2) $JSON::PP::a$JSON::PP::b 变量保存被比较的哈希键。 但请注意,哈希引用指的是 JSON 输出,因为它是从叶节点向上构建的。它不引用您的原始数据结构。这似乎使编写比较器的任务变得更加棘手。祝你好运。

my $sorter = sub {
    my ($json_pp_object, $hash_ref) = @_;

    # Write your own comparator here.
};

my $output = $js->sort_by($sorter)->encode($h);

【讨论】:

  • 预期排序:第一个按哈希键的字母顺序,第二个按第一个 hashref 子键的字母顺序。或者,(第二个),通过“pos”的值(在弄清楚排序如何在嵌套结构上工作之后)进行数值计算。
  • 个人说明:这是一个类似的问题:stackoverflow.com/questions/4041762/…
  • 编写您自己的分拣机时的注释。看来 $JSON::PP::VERSION = '2.27200' 没有将 JSON::PP 对象作为第一个参数。对于您的最后一个示例,版本 >= 2.27200 的排序器需要使用我的 $hashref = shift;
猜你喜欢
  • 2016-05-12
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多