假设您提供了数据,以下循环将使用扩展数组创建一个新哈希。该算法假定组将按排序顺序解析(group2 将仅依赖于 group1,group3 在 1 / 2 上,...)。
my %expanded;
for my $group (sort keys %HoA) {
my %seen;
$expanded{$group} = [
grep {not $seen{$_}++}
map {exists $expanded{$_} ? @{$expanded{$_}} : $_}
@{$HoA{$group}}
];
print "$group: @{ $expanded{$group} }\n"
}
打印:
组 1:用户 1 用户 2
组 2:用户 1 用户 2 用户 3
组 3:用户 1 用户 2 用户 3
组 4:用户 1 用户 2 用户 3
如果您不能假设解决顺序,则以下内容有点蛮力,但应该可以:
my %HoA = (
group1 => [ "user1", "user2" ],
group2 => [ "group1", "user3" ],
group3 => [ "group1", "group2" ],
group4 => [ "user5", "group5" ],
group5 => [ "group3", "user2" ],
);
my @to_expand = keys %HoA;
my %final;
my $tries = @to_expand;
to_expand: while (@to_expand and $tries) {
my $next = shift @to_expand;
my (@users, @groups);
for (@{ $HoA{$next} }) {
if (/^group/) {
push @groups, $_;
} else {
push @users, $_;
}
}
for my $group (@groups) {
if (exists $final{$group}) {
push @users, @{$final{$group}}
} else {
$tries--;
push @to_expand, $next;
next to_expand;
}
}
$tries++;
my %seen;
$final{$next} = [grep {not $seen{$_}++} @users];
}
if (@to_expand) {
print "error with groups: @to_expand\n";
}
for (sort keys %final) {
print "$_: @{$final{$_}}\n";
}
打印:
组 1:用户 1 用户 2
组 2:用户 3 用户 1 用户 2
组 3:用户 1 用户 2 用户 3
组 4:用户 5 用户 2 用户 1 用户 3
组 5:用户 2 用户 1 用户 3
如果出现错误(例如 group3 取决于 group5),那么您将获得以下输出:
组错误:group4 group5 group3
组 1:用户 1 用户 2
组 2:用户 3 用户 1 用户 2
为此可能有更好的算法。