【发布时间】:2012-06-26 14:35:53
【问题描述】:
我正在尝试整理从 JSON 读取的 Perl 中的大型数据结构。两个典型的元素看起来像这样(在 JSON 中):
[
[ [ {'payload':'test'} ], [ [ {'payload':'reply'} ], [] ] ],
[ [ {'payload':'another thread'} ]
]
我想完全删除该元素底部的空 arrayref,并将每个仅包含单个 hashref 的 arrayref 替换为包含的 hashref。也就是说,结果应该是这样的:
[
[ {'payload':'test'}, [ {'payload':'reply'} ] ],
[ {'payload':'another thread'} ]
]
目前我的代码如下:
use v5.12;
use strict;
use warnings;
use JSON::XS;
use Data::Walk;
sub cleanup {
if (ref $_ eq 'ARRAY') {
if (scalar(@{$_}) == 0) {
die 'mysteriously I never reach this branch!';
while (my ($key,$value) = each @{$Data::Walk::container}) {
if ($value == $_) {
delete ${$Data::Walk::container}[$key]
}
}
} elsif (scalar(@{$_}) == 1 and ref @{$_}[0]) {
$_ = @{$_}[0];
} else {
my $tail = ${$_}[scalar(@{$_})-1];
if (ref $tail eq 'ARRAY' and scalar(@{$tail}) == 0) {
$#{$_}--;
}
}
}
}
sub get {
my $begin = shift;
$begin = 0 unless $begin;
my $end = shift();
$end = $begin + 25 unless $end;
my $threads;
{
local $/;
open(my $f, '<emails.json');
$threads = decode_json <$f>;
close($f);
}
$threads = [ @{$threads}[$begin .. $end] ];
walkdepth(\&eliminate_singleton, $threads);
return $threads;
}
print JSON::XS->new->ascii->pretty->encode(&get('subject:joke'));
虽然它成功删除了空数组引用,但它未能折叠单例。如何更正此代码以使其可以折叠单例?
【问题讨论】:
-
+1 提出一个好问题。你应该称自己为 Hedgepruner。 ;-)
-
如果您发布一个演示该问题的程序,这将非常有帮助。就目前而言,代码运行一个程序
notmuch,查询subject:joke以生成JSON数据。这些东西对于问题来说是微不足道的,对于那些试图帮助你的人来说是未知的,并且需要大量的工作来分解你的代码并将相关部分与不相关部分区分开来。您展示了一些数据很好,但就目前而言,它是无效的 JSON,并且查看如何在您的程序中使用它并非易事。结果是答案数量非常少。
标签: perl data-structures perl-data-structures traversal