Получить пересечение двух списков строк в Perl - PullRequest
7 голосов
/ 21 октября 2011

В главе 4, раздел 4.8 (Вычисление объединения, пересечения или различия уникальных списков), Поваренная книга Perl предоставляет этот метод для получения пересечения двух списков целых чисел:

@a = (1, 3, 5, 6, 7, 8);
@b = (2, 3, 5, 7, 9);
...
foreach $e (@a, @b) {
    $union{$e}++ && $isect{$e}++
}
@union = keys %union;
@isect = keys %isect;

Я хочу, чтобы это было сделано (без учета регистра) для двух списков строк. Любой эффективный метод, пожалуйста?

Ответы [ 3 ]

15 голосов
/ 21 октября 2011

Array :: Utils - это то, что вы ищете.

use Array::Utils qw(:all);

my @a = qw( a b c d );
my @b = qw( c d e f );

my @isect = intersect(@a, @b);
print join(",",@isect) . "\n";

Это дает ожидаемый результат

c,d

Редактировать: Я не заметил, что вы хотели, чтобы это было сделано без учета регистра. В этом случае вы можете заменить @a на map{lc}@a (и аналогично на @b).

3 голосов
/ 11 января 2013

Вот один map / grep подход:

my @a = qw(Perl PHP Ruby Python C JavaScript);
my @b = qw(erlang java perl python c snobol lisp);
my @intersection =
    grep { defined }
        @{ { map { lc ,=> $_ } @a } }
           { map { lc } @b };

# @intersection = qw(Perl Python C)
1 голос
/ 21 октября 2011

Наименьшее количество изменений, которое требуется от исходного решения. Просто строчные буквы.

@a = qw( a b c d );
@b = qw( C D E F );
...
foreach $e (@a, @b) { 
    $union{lc $e}++ && $isect{lc $e}++ 
}

@union = keys %union;
@isect = keys %isect;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...