gpt4 book ai didi

perl - 从复杂的 Perl 数据结构中删除空数组引用和单例数组引用

转载 作者:行者123 更新时间:2023-12-03 21:40:17 24 4
gpt4 key购买 nike

我正在尝试整理从 JSON 读取的 Perl 中的大型数据结构。两个典型的元素如下所示(在 JSON 中):

[
[ [ {'payload':'test'} ], [ [ {'payload':'reply'} ], [] ] ],
[ [ {'payload':'another thread'} ]
]

我想完全删除该元素底部的空 arrayref,并用包含的 hashref 替换每个仅包含单个 hashref 的 arrayref。换句话说,结果应该是这样的:

[
[ {'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'));

虽然它成功地移除了空的 arrayref,但它无法折叠单例。如何更正此代码以使其可以折叠单例?

最佳答案

我看到您想删除作为数组元素的空数组,但我不明白用对其元素的引用替换每个单独的 arrayref。您的意思是用其内容替换作为单元素数组的每个哈希值吗?

所以

[
"data1",
[],
"data3",
]

转换为

[
"data1",
"data3",
]

{
"key1" : ["val1", "val2"],
"key2" : ["val3"],
"key3" : ["val4", "val5"],
}

转换为

{
"key1" : ["val1", "val2"],
"key2" : "val3",
"key3" : ["val4", "val5"],
}

在您的程序中,后者对应于 "tags": ["inbox"] 成为 "tags": "inbox"

如果是这种情况,那么此版本的 eliminate_singleton 将执行您想要的操作。

它从容器节点获取 View 并检查是否需要修改其中的任何内容。从节点本身的角度来看可能会导致节点在被扫描时被修改,这将破坏程序。实际上,从数组末尾向后循环是安全的,因为它不会删除任何未访问的节点。

use Scalar::Util 'reftype';

sub eliminate_singleton {

my $node = $_;
my $type = reftype $node // '';

if ($type eq 'ARRAY') {
for (my $i = $#$node; $i >= 0; $i--) {
my $subnode = $node->[$i];
my $subtype = reftype($subnode) // '';
delete $node->[$i] if $subtype eq 'ARRAY' and @$subnode == 0;
}
}
elsif ($type eq 'HASH') {
for my $k (keys %$node) {
my $subnode = $node->{$k};
my $subtype = reftype($subnode) // '';
if ($subtype eq 'ARRAY' and @$subnode == 1) {
$node->{$k} = $node->{$k}[0];
};
}
}
}

关于perl - 从复杂的 Perl 数据结构中删除空数组引用和单例数组引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11209758/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com