Perl: как отсортировать структуру JSON по атрибутам ключа, отличным от корневых - PullRequest
8 голосов
/ 20 августа 2010

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", то есть плотность, глубина_ин_м, 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."
        }
}

1 Ответ

14 голосов
/ 20 августа 2010

Я не уверен, что понимаю, как вы хотите отсортировать вывод JSON - кроме сортировки по ключу хеша. Если это все, что вы хотите, просто передайте методу canonical истинный аргумент.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...