Как найти нечувствительные к регистру уникальные элементы двух массивов в Perl? - PullRequest
1 голос
/ 07 января 2009

У меня есть три массива.

  • @ array1, содержащий имена файлов
  • @ array2, содержащий имена файлов
  • @ уникальных, которые я хочу содержать уникальные предметы

Я использую следующий код для сравнения двух массивов и вывода третьего массива, который содержит уникальные имена файлов.

@test{@array1} = ();
@unqiue = grep {!exists $test{$_}} @array2;

Однако выходные данные чувствительны к регистру, как мне изменить их, чтобы они были нечувствительными к регистру?

Спасибо


Привет, извините, я думаю, что не очень хорошо задал свой вопрос!

Я сохраняю старый массив дорожек, содержащий дорожки, которые я уже воспроизводил, и затем у меня есть новый массив дорожек, из которого я хочу выбрать. Я хочу сравнить новые треки со старым массивом треков, чтобы убедиться, что я получаю только те треки, которые являются уникальными для выбора.

Таким образом, в настоящее время вывод:

Unique Tracks:
\my Music\Corrupt Souls\b-corrupt.mp3
\My Music\gta4\10 - Vagabond.mp3
\My Music\gta4\14 - War Is Necessary.mp3
\My Music\Back To Black\05 Back to Black.mp3

Мне нужно, чтобы результат просто возвращал треки 10, 14 и 05, так как первый трек, b-поврежденный, уже находится в старом массиве треков, только случай отличается.

Заранее спасибо за помощь


#!/usr/bin/perl
$element = '\\My Music\\Corrupt Souls\\b-corrupt.mp3';
push (@oldtrackarray, $element);

$element = '\\My Music\\Back To Black\\03 Me and Mr Jones.mp3';
push (@oldtrackarray, $element);

$element = '\\My Music\\Jazz\\Classic Jazz-Funk Vol1\\11 - Till You Take My Love [Original 12 Mix].mp3';
push (@oldtrackarray, $element);

$element = '\\My Music\\gta4\\01 - Soviet Connection (The Theme From Grand Theft Auto IV).mp3';
push (@oldtrackarray, $element);

$element = '\\My Music\\gta4\\07 - Rocky Mountain Way.mp3';
push (@oldtrackarray, $element);

$element = '\\My Music\\gta4\\02 - Dirty New Yorker.mp3';
push (@oldtrackarray, $element);

print "Old Track Array\n";
for($index=0; $index<@oldtrackarray+1; $index++) {
    print "$oldtrackarray[$index]\n";}


$element = '\\my Music\\Corrupt Souls\\b-corrupt.mp3';
push (@newtrackarray, $element);

$element = '\\My Music\\gta4\\10 - Vagabond.mp3';
push (@newtrackarray, $element);

$element = '\\My Music\\gta4\\14 - War Is Necessary.mp3';
push (@newtrackarray, $element);

$element = '\\My Music\\Back To Black\\05 Back to Black.mp3';
push (@newtrackarray, $element);

print "New Tracks\n";
for($index=0; $index<@newtrackarray+1; $index++) {
    print "$newtrackarray[$index]\n";
}

@test{@oldtrackarray} = ();
@uninvited = grep {!exists $test{$_}} @newtrackarray;

print "Unique Tracks:\n";
for($index=0; $index<$#uninvited+1; $index++) {
    print "$uninvited[$index]\n";
}

Ответы [ 4 ]

8 голосов
/ 07 января 2009
@test{ map { lc } @array1 } = ();
@new_ones = grep { !exists $test{lc $_} } @array2;

Если вы хотите добавить список @new_ones к тем, которые уже есть в @array1, получая список всех уникальных предметов, которые вы видели до сих пор:

push @array1, @new_ones;
6 голосов
/ 07 января 2009

Вы хотите только уникальные элементы из @array2? Если вам нужны все уникальные элементы из обоих массивов, вам нужно просто просмотреть все элементы и вспомнить, какие из них вы видели раньше:

my %Seen = ();
my @unique = grep { ! $Seen{ lc $_ }++ } @array1, @array2;

Вы опубликовали обновление, в котором говорите, что хотите выбрать элементы, которые вы еще не обработали. Вместо двух массивов рассмотрите один хеш, чтобы хранить все ваши данные в одном месте. Начните с инициализации всего со значением 0:

my %Tracks = map { $_, 0 } @all_tracks;

Когда вы обрабатываете (или проигрываете) один из элементов, установите для его значения хеш-функции истинное значение:

$Tracks{ $playing } = 1;

Если вы хотите, чтобы дорожки, которые вы не обработали, выберите ключи, значение которых не соответствует действительности:

@not_processed = grep { ! $Tracks{$_} } keys %Tracks;

Если у вас есть вопрос о ваших товарах, вы просто задаете %Tracks правильный вопрос.

1 голос
/ 07 января 2009

Это должно сработать ..

    $test{lc $_} = 1 foreach @array1;  @unique = grep { ! exists $test{lc $_}} @array2;
0 голосов
/ 07 января 2009

Хотя я в целом согласен с решением Брайана %Seen, в исходном вопросе я заметил, что в выводе отображаются названия песен в правильном регистре.

Второй хэш (то есть дизайн с вывернутым наизнанку), по направлениям:

my %title;
foreach (@array1, @array2) {
    my $lc = lc $_;
    $title{$lc} = $_ unless $title{$lc} && $title{$lc} =~/[:upper:][:lower:]/;
        # ie don't overwrite if saved title matches '[A-Z][a-z]'
}

Затем используйте содержимое %title в выводе.

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