user3606329 user3606329 - 5 months ago 24
JSON Question

Hash::Ordered versus Tie::IxHash with JSON::XS encode

I'm trying

instead of
Tie::IxHash
, because it seems to be faster.

While
Tie::IxHash
is working fine, I struggle with 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"
   }
}