How to find case insensitive unique elements of two arrays in Perl?

I have three arrays.

  • @ array1 containing filenames
  • @ array2 containing filenames
  • @unique i want to contain unique elements

I am using the following code to compare two arrays and output a third array that contains unique filenames.

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

      

However the output is case sensitive, how can I change it to be case insensitive?

thank


Hi Sorry, I think I didn't ask my question very well!

I save an old track array containing the tracks I have already played and then I have a new track array that I want to select. I want to compare the new tracks with the old track array to ensure that I only get tracks that are unique to pick.

So at the moment the output is:

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

I need the result to just return tracks 10, 14, and 05, since the first track, b-corrupt, is already in the old track array, only the case is different.

Thanks in advance for your help

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

+1


source to share


4 answers


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

      

If you want to add a list @new_ones

to those already in @array1

, thereby creating a list of all unique items that have been viewed so far:



push @array1, @new_ones;

      

+8


source


Do you only need unique items from @array2

? If you want all the unique elements from both arrays, you just need to go through all the elements and remember which ones you saw before:

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

      

You sent an update where you say you want to select items that have not yet been processed. Consider a single hash instead of two arrays to keep all of your data in one place. Start by initializing everything with the value 0:

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

      

When you process (or reproduce) one of the elements, set its hash value to a true value:



$Tracks{ $playing } = 1;

      

If you want the tracks that you haven't processed, select the keys where the value doesn't match true:

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

      

Whenever you have a question about your products, you are simply asking the %Tracks

right question.

+6


source


This should do the trick.

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

      

+1


source


While I agree with brian's solution %Seen

in general, I noticed in the original question that matching cover titles are displayed in the output.

Second hash (i.e. the design with the least bend), along the lines:

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]'
}

      

Then use the output %title

in the output file.

0


source







All Articles