Вы можете временно использовать HoH вместо HoA.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
<DATA>; # Skip header.
my %data;
my %seen;
while (<DATA>) {
chomp;
my ($app_id, $ci_name, $app_name) = split /,/;
$data{$ci_name}{$app_id} //= { app_id => $app_id, app_name => $app_name };
}
# Convert HoH to HoA.
$data{$_} = [ values(%{ $data{$_} }) ]
for keys(%data);
print Dumper(\%data);
Приведенное выше сохраняет первый из дубликатов и не сохраняет порядок. Измените //=
на =
, чтобы сохранить последние дубликаты. Продолжайте читать, чтобы найти решение, которое сохраняет порядок.
Ниже приведен распространенный способ удаления дубликатов при сохранении порядка:
my %seen;
my @uniq = grep !$seen{$_}++, @values;
Мы можем адаптировать эту идиому к нашим потребностям.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
<DATA>; # Skip header.
my %data;
my %seen;
while (<DATA>) {
chomp;
my ($app_id, $ci_name, $app_name) = split /,/;
push @{ $data{$ci_name} }, { app_id => $app_id, app_name => $app_name }
if !$seen{$ci_name}{$app_id}++;
}
print Dumper(\%data);
Приведенное выше сохраняет первый из дубликатов и сохраняет порядок.
Оба этих решения имеют скорость O (N), тогда как ранее опубликованное решение имеетскорость O (N 2 ), поэтому это решение масштабируется намного лучше. Хотя, если честно, ранее опубликованное решение имеет практическую скорость O (N), если нет много дубликатов.
Обратите внимание, как я добавил <DATA>
перед циклом? Это гораздо лучше, чем пропускать все строки, содержащие app_id
в любом месте строки!