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

Hi Monks - I have two arrays
@numbers = ('25', '12', '32','56','45','21','65'); @needed = ('25','32','45','65');
I want to be able to iterate through @numbers, comparing each value to @needed. When there is a match, I want to get the match and all the values until the next match.
e.g. get 25 12 32 and 45 21 65
Thankyou monks, I appreciate your help. x
for (my $i=0; $i<@numbers; $i++) { # psudocode # # if $numbers[$i] matches a value in @needed; # push @found, all the numbers until the next match for (my $k = 0; $k < @needed; $k++) { if ($numbers[$i] == $needed[$k]) { push @found, $numbers[$i]; # not sure how to carry on until the next match! } } } }

Replies are listed 'Best First'.
•Re: comparing values between two arrays
by merlyn (Sage) on May 20, 2003 at 10:08 UTC
    So, all these years, you've been wondering what the three-dot version of the flip-flop (..) operator was for? Well, here it is!
    my @numbers = ('25', '12', '32','56','45','21','65'); my @needed = ('25','32','45','65'); my %needed_hash = map { $_ => 1 } @needed; my @result = grep { $needed_hash{$_} ... $needed_hash{$_} } @numbers; print "@result\n";
    The grep test starts being true when the item is found in the hash, and also stops being true with the same test. But it won't test the stop condition on the same round as the start condition! That's why the three dots. With only two dots, it would have found the stop condition on the same item.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: comparing values between two arrays
by broquaint (Abbot) on May 20, 2003 at 10:15 UTC
    Not as groovy as merlyn's post, but I'd already put this together so here it is anyway
    my @numbers = ('25', '12', '32','56','45','21','65'); my @needed = ('25','32','45','65'); my @flipflop = map [$needed[$_], $needed[$_ + 1]], grep { $_ % 2 == 0 } 0 .. $#needed; for(@numbers) { print "$_ " and next if /\A$flipflop[0]->[0]\z/ .. /\A$flipflop[0]->[1]\z/; shift @flipflop and print "\n"; } __output__ 25 12 32 45 21 65
    See. map, grep and perlop for more info.
    HTH

    _________
    broquaint

Re: comparing values between two arrays
by dbush (Deacon) on May 20, 2003 at 10:24 UTC

    merlyn and broquaint beat me to it with much better solutions, but here is my effort for what its worth.

    Regards,
    Dom.

    use strict; use warnings; use Data::Dumper; my @numbers = ('25', '12', '32','56','45','21','65'); my @needed = ('25','32','45','65'); my ($iNeeded, %hashNeeded, $iNumber, @result); my $bWithinMatch = 0; foreach $iNeeded (@needed) { $hashNeeded{$iNeeded} = 1 } foreach $iNumber (@numbers) { #Are we within a match? if ($bWithinMatch) {push @result, $iNumber} #Is this a needed number? if (defined $hashNeeded{$iNumber}) { #Change state $bWithinMatch = not $bWithinMatch; #If this is the start of a match, store the result if ($bWithinMatch) {push @result, $iNumber} } } print Dumper(\@result);
    Update:
    • Missed out the final line that dumps the result.
Re: comparing values between two arrays
by OM_Zen (Scribe) on May 20, 2003 at 16:51 UTC
    Hi ,

    <BR><BR> my @numbers = ('25', '12', '32','56','45','21','65'); my @needed =('25','32','45','65'); my %hashofscalars = map{ $_ ,1}@needed; my $scalar; my @res_scalars; foreach ( @numbers) { if (exists $hashofscalars{$_}){ $scalar++;push(@res_scalars ,$_); }elsif($scalar%2 != 0){ push(@res_scalars,$_) } }; print "[@res_scalars]\n"; __END__ [25 12 32 45 21 65]


    ~