user3606329 user3606329 - 5 months ago 47
JSON Question

Perl - Hash::Ordered with JSON::XS encode

I'm trying Hash::Ordered after Tie::IxHash, because it seems to be faster. While Tie::IxHash is working fine, I struggle some problems with Hash::Ordered. The point is to have the hashes ordered (which are usually random in Perl).

use Hash::Ordered;
use JSON::XS;
use Data::Dumper;
use strict;
use warnings;

my $json = JSON::XS->new;
my $oh = Hash::Ordered->new;
$oh->push('result' => { 'counter' => "123" }, 'number' => { 'num' => '55' });
my @r = $oh->as_list;
$json->pretty(1);
my $jsondata = $json->encode(\@r);
print Dumper $jsondata;


The result is odd:

[
"result",
{
"counter" : "123"
},
"number",
{
"num" : "55"
}
]


Here is the working example with Tie::IxHash, I try to get the same results with Hash::Ordered.

use Data::Dumper;
use Tie::IxHash;
use JSON::XS;
use strict;
use warnings;

my $json = JSON::XS->new;
my %h;
tie(%h, 'Tie::IxHash', result => { counter => "123" }, number => { num => '55' });
$json->pretty(1);
my $pretty_json = $json->encode(\%h);
print Dumper $pretty_json;


Output

{
"result" : {
"counter" : "123"
},
"number" : {
"num" : "55"
}
}

Answer

Use the Hash::Ordered tied interface:

my $json = JSON::XS->new;

tie my %hash, "Hash::Ordered";

$hash{'result'} = { 'counter' => "123" };
$hash{'number1'} = { 'num' => '1' };
$hash{'number2'} = { 'num' => '2' };
$hash{'number3'} = { 'num' => '3' };
$hash{'last'} = { 'num' => 'last' };

$json->pretty(1);
my $jsondata = $json->encode(\%hash);

And the JSON data you get is:

{
   "result" : {
      "counter" : "123"
   },
   "number1" : {
      "num" : "1"
   },
   "number2" : {
      "num" : "2"
   },
   "number3" : {
      "num" : "3"
   },
   "last" : {
      "num" : "last"
   }
}
Comments