Perl - 使用递归函数将数组的散列转换为数组的数组
Perl - Convert hash of arrays to array of arrays using recursive function
我在我的脚本中创建了以下数组散列(称为 $hoa):
$hoa = {
'Continents' => [
'Continent1',
'Continent2',
'Continent3'
],
'Earth' => [
'Continents'
],
'Continent1' => [
'Country1'
],
'Continent3' => [
'Country3'
],
'Country1' => [
'City1',
'City2'
]
};
我想将其转换为数组数组,以便在脚本的后面部分使用。数组的数组应如下所示:
$aoa=[
['Earth','Continents','Continent1','Country1','City1'],
['Earth','Continents','Continent1','Country1','City2'],
['Earth','Continents','Continent2'],
['Earth','Continents','Continent3','Country3']
];
我创建了以下代码来完成这项工作,但它没有按预期工作。
sub CreateArrofArr
{
my $arg={@_};
my $member=$arg->{member};
my $hoa=$arg->{hoa};
my $aoa=[];
if(exists($hoa->{$member}))
{
for(my $i=0; $i<scalar(@{$hoa->{$member}}); $i++)
{
my $elem=@{$hoa->{$member}}->[$i];
my $temp_arr=[];
if(!exists($hoa->{$elem}))
{
push(@{$temp_arr},$member);
push(@{$temp_arr},$elem);
push(@{$aoa},$temp_arr);
}
else
{
push(@{$aoa},@{CreateArrofArr(member=>$elem,hoa=>$hoa)})
}
}
}
return ($aoa);
}
my $aoa=CreateArrofArr(member=>"Earth",hoa=>$hoa);
print Dumper($aoa);
$aoa 返回如下(这不是我所期望的):
$VAR1 = [
[
'Country1',
'City1'
],
[
'Country1',
'City2'
],
[
'Continents',
'Continent2'
],
[
'Continent3',
'Country3'
]
];
请帮忙。
最小的变化:
sub CreateArrofArr {
my $arg = { @_ };
my $member = $arg->{member};
my $hoa = $arg->{hoa};
my $aoa = [];
if (exists($hoa->{$member})) {
for (my $i=0; $i<scalar(@{$hoa->{$member}}); $i++) {
my $elem = $hoa->{$member}->[$i];
push @{$aoa},
map { [ $member, @$_ ] }
@{ CreateArrofArr( member => $elem, hoa => $hoa ) };
}
} else {
my $temp_arr = [];
push @{$temp_arr}, $member;
push @$aoa, $temp_arr;
}
return $aoa;
}
my $aoa = CreateArrofArr( member => "Earth", hoa => $hoa );
上面的清理版本:
sub flatten {
my ($tree, $current) = @_;
my $node = $tree->{$current};
return [ $current ] if !$node;
return
map { [ $current, @$_ ] }
map { flatten($tree, $_) }
@$node;
}
my @flattened = flatten($tree, 'Earth');
另一种方法是将路径向下传递到树的根,而不是继续添加到您的路径。这稍微简化了事情。
sub flatten {
my $tree = shift;
my $node = $tree->{ $_[-1] };
return [ @_ ] if !$node;
return map { flatten($tree, @_, $_) } @$node;
}
my @flattened = flatten($tree, 'Earth');
我在我的脚本中创建了以下数组散列(称为 $hoa):
$hoa = {
'Continents' => [
'Continent1',
'Continent2',
'Continent3'
],
'Earth' => [
'Continents'
],
'Continent1' => [
'Country1'
],
'Continent3' => [
'Country3'
],
'Country1' => [
'City1',
'City2'
]
};
我想将其转换为数组数组,以便在脚本的后面部分使用。数组的数组应如下所示:
$aoa=[
['Earth','Continents','Continent1','Country1','City1'],
['Earth','Continents','Continent1','Country1','City2'],
['Earth','Continents','Continent2'],
['Earth','Continents','Continent3','Country3']
];
我创建了以下代码来完成这项工作,但它没有按预期工作。
sub CreateArrofArr
{
my $arg={@_};
my $member=$arg->{member};
my $hoa=$arg->{hoa};
my $aoa=[];
if(exists($hoa->{$member}))
{
for(my $i=0; $i<scalar(@{$hoa->{$member}}); $i++)
{
my $elem=@{$hoa->{$member}}->[$i];
my $temp_arr=[];
if(!exists($hoa->{$elem}))
{
push(@{$temp_arr},$member);
push(@{$temp_arr},$elem);
push(@{$aoa},$temp_arr);
}
else
{
push(@{$aoa},@{CreateArrofArr(member=>$elem,hoa=>$hoa)})
}
}
}
return ($aoa);
}
my $aoa=CreateArrofArr(member=>"Earth",hoa=>$hoa);
print Dumper($aoa);
$aoa 返回如下(这不是我所期望的):
$VAR1 = [
[
'Country1',
'City1'
],
[
'Country1',
'City2'
],
[
'Continents',
'Continent2'
],
[
'Continent3',
'Country3'
]
];
请帮忙。
最小的变化:
sub CreateArrofArr {
my $arg = { @_ };
my $member = $arg->{member};
my $hoa = $arg->{hoa};
my $aoa = [];
if (exists($hoa->{$member})) {
for (my $i=0; $i<scalar(@{$hoa->{$member}}); $i++) {
my $elem = $hoa->{$member}->[$i];
push @{$aoa},
map { [ $member, @$_ ] }
@{ CreateArrofArr( member => $elem, hoa => $hoa ) };
}
} else {
my $temp_arr = [];
push @{$temp_arr}, $member;
push @$aoa, $temp_arr;
}
return $aoa;
}
my $aoa = CreateArrofArr( member => "Earth", hoa => $hoa );
上面的清理版本:
sub flatten {
my ($tree, $current) = @_;
my $node = $tree->{$current};
return [ $current ] if !$node;
return
map { [ $current, @$_ ] }
map { flatten($tree, $_) }
@$node;
}
my @flattened = flatten($tree, 'Earth');
另一种方法是将路径向下传递到树的根,而不是继续添加到您的路径。这稍微简化了事情。
sub flatten {
my $tree = shift;
my $node = $tree->{ $_[-1] };
return [ @_ ] if !$node;
return map { flatten($tree, @_, $_) } @$node;
}
my @flattened = flatten($tree, 'Earth');