Мы хотим знать, к каким группам принадлежит каждый член, поэтому мы создадим Hash of Arrays (HoA) с ключом участника, который содержит все группы, к которым принадлежит член (напрямую).
push @{ $hash{$key} }, $value;
является распространенным способом построения HoA.
Как только этот HoA будет создан, мы определим группы, к которым принадлежит IP-адрес, затем мы определим группы, к которым принадлежит каждая из этих групп, и т. Д.
Если IP принадлежит двум двум группам, которые обе принадлежат к одной и той же группе (напрямую или иначе), нам нужно отфильтровать группы, которые мы видели ранее.
my %seen; my @unique = grep !$seen{$_}++, @values;
- это распространенный способ отфильтровать дубликаты.
Решение:
use strict; # ALWAYS use this.
use warnings; # ALWAYS use this.
use feature qw( say );
use Sort::Key::Natural qw( natsort ); # Optional. Can use sort or leave unsorted instead.
use Text::CSV_XS qw( ); # Faster than Text::CSV, but otherwise identical.
my $ip = "10.1.1.1";
my $qfn = "text.csv";
my $csv = Text::CSV_XS->new({
auto_diag => 2, # Die on errors.
binary => 1, # Should always have this.
});
# "DATA" already exists, and you shouldn't be using global vars.
open(my $fh, "<:encoding(iso-8859-7)", $qfn)
or die("Can't open \"$qfn\": $!\n");
my %belongs_to;
while ( my $row = $csv->getline($fh) ) { # Proper way to use $csv
my ($member, $group) = @$row;
# Add $group to the array referenced by $belongs_to{$member}.
# The array is autovivified as if we had used « $belongs_to{$member} //= []; ».
push @{ $belongs_to{$member} }, $group;
}
# Recursively determine to which groups $ip belongs.
my %groups;
my @groups;
my @todo = $ip;
while (@todo) {
my $member = shift(@todo);
# Add every group we haven't encountered yet to @groups and @todo.
my @new_groups = grep !$groups{$_}++, @{ $belongs_to{$member} };
push @groups, @new_groups;
push @todo, @new_groups;
}
@groups = natsort @groups; # Make the results more presentable.
say for @groups;
(Существуют способы оптимизации последней части, но выгоды минимальны, и предельная ясность здесь важнее.)