> Thanks! ... And thanks for the example to go with it: works great for me.
Your welcome, I'm learning a lot from interesting questions.
The code is mostly adopted from the perldoc though and could be written in a more generic way.
I also like the fact that JSON::PP automatically detects hashes ordered via tie interface.
> I knew that JSON used JSON::PP or JSON::XS under the hood,
Not only under the hood, you can even use both modules in the same code, as long as you are restricting one of them to pure OO. =)
use warnings;
use strict;
use autodie;
use JSON::PP qw//; # don't export anything
use JSON;
use Test::More;
use 5.010;
my @order = qw/id disp ver auth/;
my $dat = [ ({ id => 'a', disp => 'a', ver => 'a', auth => 'a' })x2 ];
+ # dummy data
local $\ = "\n";
#print 'Unsorted => ', JSON->new->indent->space_after->encode( $dat );
#print 'Alpha Sorted => ', JSON->new->indent->space_after->canonical->
+encode( $dat );
print "Pryrt's Order => ",
my $pryrt = manual_ordered_json( $dat, \@order );
# --- Sorting with JSON::PP
my %ORDER;
@ORDER{@order} = 1 .. @order;
my $sort = sub {
package JSON::PP;
($ORDER{$a} // 1e999) <=> ($ORDER{$b} // 1e999)
or
$a cmp $b
};
print "LanX' Order => ",
my $lanx = JSON::PP->new->sort_by($sort)->indent->space_after->enc
+ode( $dat );
# # --- erase whitespace diffs
# s/\s//g for $pryrt, $lanx;
is($lanx,$pryrt,"same JSON");
done_testing();
use Data::Dumper;
sub manual_ordered_json{
my @list = @{$_[0]};
my @ordr = @{$_[1]};
my $out = "[\n";
for my $i ( 0 .. $#list ) {
my $h = $list[$i];
$out .= " {\n";
for my $j ( 0 .. $#ordr ) {
my $k = $ordr[$j];
next unless defined $k;
next unless exists $h->{$k};
$out .= sprintf qq| "%s": "%s"|, $k, $h->{$k} // '<un
+def>';
$out .= ',' if $j < $#ordr;
$out .= "\n";
}
$out .= " }";
$out .= "," if $i < $#list;
$out .= "\n";
}
$out .= "]\n";
return $out;
}
|