С помощью Perl, когда вы хотите получить уникальные значения из какой-либо коллекции, подумайте о том, как вы можете использовать хэш, чтобы помочь вам автоматически свернуть дубликаты или, по крайней мере, помочь вам запомнить, какие значения вы уже видели. Например, см. How can I get the unique keys from two hashes? в разделе 4 часто задаваемых вопросов по Perl.
Ваш случай немного сложнее, потому что у вас есть наборы сменных имен, поэтому вы должны записать эту информацию.
sub add_names {
my $equivalent = shift;
for (@_) {
my @names = map lc, @$_;
for (@names) {
die "$0: overlap on name '$_'" if exists $equivalent->{$_};
$equivalent->{$_} = \@names;
}
}
$equivalent;
}
Здесь $equivalent
является ссылкой на хэш. После вызова
add_names $equivalent, [ qw/ Rajesh Ram peter/];
хэш будет иметь ключи 'rajesh'
, 'ram'
и 'peter'
, значение которых все [ 'rajesh', 'ram', 'peter' ]
. Структурирование этого способа означает, что мы можем получить полный набор имен независимо от того, с каким именем мы сталкиваемся в первую очередь.
Заметим также, что вы можете сложить несколько наборов имен в одном вызове, как в
add_names $equivalent, [ qw/ Rajesh Ram peter/],
[ qw/ Jim Bob Bubba/];
С именами наметил, теперь мы можем обработать список и сохранить первое имя из каждого набора, который мы найти. Для данного имени проверьте, видели ли мы его ранее или какие-либо его эквиваленты. Если мы его не увидели, сохраните имя и отметьте все эквиваленты, как видно.
sub remove_duplicates {
my $equivalent = shift;
my %seen;
my @uniques;
foreach my $name (@_) {
my $normal = lc $name;
unless ($seen{$normal}) {
push @uniques, $name;
++$seen{$_} for @{ $equivalent->{$normal} };
}
}
wantarray ? @uniques : \@uniques;
}
wantarray
бит на дне является общей идиома Perl для адаптации возвращаемого значения к контексту вызова. Если вызывающий объект хочет массив, мы возвращаем массив. Если нет, мы возвращаем скаляр, а именно ссылку на наш массив уникальных имен.
Собираем все вместе делает
my $equivalent = {};
add_names $equivalent, [qw/ Rajesh Ram peter /];
my @array_name = ("Rajesh","Raju","Ram","John","peter");
print $_, "\n" for remove_duplicates $equivalent, @array_name;
Выход:
Rajesh
Raju
John
Что делает ваш пример программы должны сделать с ожидаемым выходом? – flesk