2009-01-07 4 views
1

У меня есть три массива.Как найти непоследовательные уникальные элементы двух массивов в Perl?

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

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

@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 в качестве первой дорожки, б-коррумпированной, уже в старом массиве дорожки только дело обстоит иначе.

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

 

#!/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"; 
} 

+0

Все решения по-прежнему применяются, насколько я могу судить. Есть ли что-то, о чем мы не обращаемся? –

+0

Когда я пытаюсь решить проблемы, я не получаю никаких треков вообще, что немного запутывает. Новые треки произошли из «черного ящика», в котором звучат дорожки, поэтому, к сожалению, я не могу вставить все в один массив. Cheers –

+0

А ... Я думаю, что неправильно понял. Лучший способ сделать это - просто использовать @ array1 и @ array2 - забудьте @unique. Убедитесь, что @ array1 запущен пустым; с этого момента мы будем накапливать в него уникальные результаты, нажимая на него «новые» записи - см. мое отредактированное решение. –

ответ

8
@test{ map { lc } @array1 } =(); 
@new_ones = grep { !exists $test{lc $_} } @array2; 

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

push @array1, @new_ones; 
1

Это должно сделать трюк.

$test{lc $_} = 1 foreach @array1; @unique = grep { ! exists $test{lc $_}} @array2; 
6

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

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

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

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

При обработке (или играть) один из элементов, установите его хэш-значение для истинного значения:

$Tracks{ $playing } = 1; 

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

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

Всякий раз, когда у вас есть вопросы о товарах, вы просто спросите %Tracks правильный вопрос.

0

Несмотря на то, что я согласен с решением brian's %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 на выходе.

Смежные вопросы