我尝试Hash::Ordered
代替Tie::IxHash
,因为它似乎更快。
虽然Tie::IxHash
工作正常,但我遇到了Hash::Ordered
的一些问题。关键是要对哈希值进行排序(在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;
结果很奇怪:
[
"result",
{
"counter" : "123"
},
"number",
{
"num" : "55"
}
]
以下是Tie::IxHash
的工作示例,我尝试使用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;
输出
{
"result" : {
"counter" : "123"
},
"number" : {
"num" : "55"
}
}
答案 0 :(得分:4)
Hash::Ordered
的面向对象接口比绑定接口快得多,但是某些实用程序(如$json->encode
)需要真正的哈希引用
充分利用这两个世界的方法是将哈希与这些实用程序结合使用,并使用tied
提取基础Hash::Ordered
对象,以便您可以使用更快的方法调用操纵它
这个简短的节目演示了。此代码中唯一缓慢的部分是将哈希传递给encode
以转换为JSON。 push
来电不会使用绑定的界面并保持快速
use strict;
use warnings;
use Hash::Ordered;
use JSON::XS;
my $json = JSON::XS->new->pretty;
tie my %h, 'Hash::Ordered';
my $oh = tied %h;
$oh->push( result => { counter => 123 }, number => { num => 55 } );
print $json->encode(\%h), "\n";
{
"result" : {
"counter" : 123
},
"number" : {
"num" : 55
}
}
答案 1 :(得分:3)
使用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);
您获得的JSON数据是:
{
"result" : {
"counter" : "123"
},
"number1" : {
"num" : "1"
},
"number2" : {
"num" : "2"
},
"number3" : {
"num" : "3"
},
"last" : {
"num" : "last"
}
}
答案 2 :(得分:2)
上面的示例工作正常,但对于多维哈希,还需要一个额外的步骤来保持顺序。
use Hash::Ordered;
use JSON::XS;
use Data::Dumper;
use strict;
use warnings;
sub ordered_hash_ref {
tie my %hash, 'Hash::Ordered';
my $oh = tied %hash;
$oh->push(@_);
return \%hash;
};
my $json = JSON::XS->new->pretty;
tie my %h, 'Hash::Ordered';
my $oh = tied %h;
$oh->push(result => ordered_hash_ref(counter => 123, z => 5, s => 8), address => ordered_hash_ref(Vorname => 'Max',
Nachname => 'Mustermann', Strasse => 'Feldweg', Hausnummer => 45));
my $pretty = $json->encode(\%h);
print Dumper $pretty;
<强>输出强>
{
"result" : {
"counter" : 123,
"z" : 5,
"s" : 8
},
"address" : {
"Vorname" : "Max",
"Nachname" : "Mustermann",
"Strasse" : "Feldweg",
"Hausnummer" : 45
}
}