The_Rev has asked for the wisdom of the Perl Monks concerning the following question:

Hello fellow monks,

I've written the following code snippet to try and demonstrate my problem:

#!/perl/bin/perl.exe -w use strict; use vars qw(@array @data @compare $num ); $num = 0; for (0 .. 3) { @array = (); for (0 .. 1) { push @array, $num; $num ++; } push @data, [@array]; } @compare = (2, 4, 5, 6); print "Contents of \@array\n"; foreach my $record (@data) { for my $i (0 .. 1) { print $record->[$i] . " "; } print "\n"; } print "\n\nContents of \@compare\n"; foreach (@compare) { print $_, " "; }
I need to compare the two arrays (one being an array of arrays), against another array, more specifically look at the second element of @array against the contents of @compare and eliminate the duplicates from @array.

I should end up with the following values for @array ...

Contents of @array 0 1 2 3 6 7 Contents of @compare 2 4 5 6
Notice that the number 5 was the second element in @array Any ideas ?

Replies are listed 'Best First'.
Re: Array element removal
by sauoq (Abbot) on Dec 17, 2002 at 23:27 UTC
    #!/usr/bin/perl -w use strict; # Why go through all that trouble just to init a couple example arrays +? my @data = ( [0, 1], [2, 3], [4, 5], [6, 7], ); my @compare = (2, 4, 5, 6); # This is the part you want to pay attention to... my %remove; @remove{@compare} = (); my @new = grep { !exists $remove{$_->[1]} } @data; # Dump the new array for inspection. $" = ', '; print "Contents of \@new : ( "; print "[@$_], " for (@new); print ")\n";
    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Array element removal
by BrowserUk (Patriarch) on Dec 17, 2002 at 23:31 UTC

    Something like this?

    #! perl -slw use strict; use Data::Dumper; my @array = ( [0,1],[2,3],[4,5],[6,7]); my @compare = (2,4,5,6); @array = map{ $array[$_] if $array[$_][1] != $compare[$_] } 0..$#array +; print Dumper \@array;

    Examine what is said, not who speaks.

Re: Array element removal
by jdporter (Paladin) on Dec 17, 2002 at 23:07 UTC
    It's not clear how you're deciding what arrays should be removed.
    You deleted the third array from @data, because it contained the third element in @compare. That is,    [ 4, 5 ] contains 5  therefore delete. But what if it had been    [ 5, 0 ] Would it get deleted in that case?

    jdporter
    ...porque es dificil estar guapo y blanco.

      Assuming that the critical value has to be in the second position in the array, and if you don't mind building up a new array to replace the old one:
      my @new_data; for my $i ( 0 .. $#data ) { $data[$i][1] != $compare[$i] and push @new_data; } # replace: @data = @new_data;
      As an aside, you are using global variables unnecessarily. Your code will be a lot clearer and cleaner, and less error prone, if you use lexical variables properly. use warnings; and use strict; to let perl help you write better code.

      jdporter
      ...porque es dificil estar guapo y blanco.

        I assume that he doesn't want the second elements in the arrays referenced in @data to be contained anywhere in @compare. Your code only checks elements in @data and @compare with the same index. The question wasn't very well stated though.

        -sauoq
        "My two cents aren't worth a dime.";
        
      NO, I'm only looking at @array->1 elements