Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Default variable within loops

by oldwarrior32 (Sexton)
on Jun 21, 2012 at 02:33 UTC ( #977538=perlquestion: print w/ replies, xml ) Need Help??
oldwarrior32 has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks. A noob asking for your wisdom again. I did the respectively search in the monastery and the profane Google with no luck.

I have this code:

foreach(@a){ $temp = $_; $test = grep($temp eq $_,@b); print "$test\n"; }

As you can see I needed a '$temp' variable to make the thing work.

Is there a way to evaluate the grep expresion using only default variables, or the '$temp' variables is completely necessary?

Thanks for your help.

By the way, the program just output the amount of elements from array @a that are not in array @b.

Comment on Default variable within loops
Download Code
Replies are listed 'Best First'.
Re: Default variable within loops
by Kenosis (Priest) on Jun 21, 2012 at 03:16 UTC

    Here another option using smart matching:

    use Modern::Perl; my @a = 1 .. 10; my @b = 5 .. 14; say grep $_ ~~ @b, @a;

    Output:

    5678910

    Hope this helps!

      Is this Perl version specific?

        Smart matching started in Perl 5.10

Re: Default variable within loops
by aaron_baugher (Curate) on Jun 21, 2012 at 04:04 UTC
    elements from array @a that are not in array @b

    The more idiomatic way to do this is with a lookup hash. The combination of for/grep is actually two nested loops, meaning that you do a*b comparisons. A hash lookup will be faster for most situations, and clearer to anyone with much Perl experience. To show elements of @a not in @b:

    #!/usr/bin/env perl use Modern::Perl; my @a = qw/ foo bar baz /; my @b = qw/ foo bar biz /; my %b = map { $_ => 1 } @b; for (@a){ say unless $b{$_}; }

    Aaron B.
    Available for small or large Perl jobs; see my home node.

Re: Default variable within loops
by muba (Priest) on Jun 21, 2012 at 02:41 UTC
    use strict; use warnings; my @a = qw(foo bar baz); my @b = qw(foo bar biz); foreach my $temp (@a){ my @matches = grep {$temp eq $_} @b; print "Matches for $temp: ", join(", ", @matches), "\n" if @matche +s; }
Re: Default variable within loops
by frozenwithjoy (Curate) on Jun 21, 2012 at 03:03 UTC
    Three things:
    • The reason you find that you need to use $temp is that you the $_ associated with the grep is referring to an element of @b, not @a.
    • The reason you are getting a count instead of the actual matches is that you are assigning the results to a scalar, not an array.
    • One more thing... I believe you are testing for equivalency instead of checking for a pattern match. If you want to perform a typical grep, maybe use something like grep( $temp =~ /$_/, @b )
Re: Default variable within loops
by stevieb (Priest) on Jun 21, 2012 at 03:12 UTC

    I couldn't come up with anything shorter than muba. I tried, but you need at least one temp var (afaict), or else the $_ will confuse iteslf.

    my @a = qw( a b c ); my @b = qw( a 3 c ); for my $elem (@a){ print $elem if grep { $elem eq $_ } @b; }
Re: Default variable within loops
by Kenosis (Priest) on Jun 21, 2012 at 04:44 UTC

    elements from array @a that are not in array @b

    Here's another option for that:

    use Modern::Perl; use List::Compare; my @a = 1 .. 10; my @b = 5 .. 14; my $lc = List::Compare->new(\@a, \@b); say $lc->get_unique;

    Output:

    1234

    ps Aaron, I always appreciate your postings...

Re: Default variable within loops
by cheekuperl (Monk) on Jun 21, 2012 at 03:09 UTC
    the program just output the amount of elements from array @a that are not in array @b
    There's a recipe given in Programming Perl for this.

    For default variable within loops- I think its not possible (atleast on Perl v5.8.9). I tried this:
    @a=(11,22,33,44,55); @b=(22,44,66,17); foreach (@a) # $_ gets one value from @a { @tested=grep {$_ == $::_} @b; # Had $_ been lexical for grep, $::_ w +ould've been a global } print "\n@tested"; #Doesn't work as expected...$_ and $::_ both are sa +me and get each value from @b
    Doesn't look like $_ can be made lexical to grep block.
Re: Default variable within loops
by zentara (Archbishop) on Jun 21, 2012 at 11:59 UTC
Re: Default variable within loops
by Anonymous Monk on Jun 21, 2012 at 13:03 UTC
    Although variables such as $_ are available, they are cryptic, and visually ambiguous when there are nested loops.   Avoid the practice.   Be clear.   Don’t write code that will break merely because you changed it.
Re: Default variable within loops
by oldwarrior32 (Sexton) on Jun 21, 2012 at 03:58 UTC

    Thanks all!

    Just wanted to be sure I was doing the right thing.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://977538]
Approved by muba
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (12)
As of 2015-08-28 07:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The oldest computer book still on my shelves (or on my digital media) is ...













    Results (335 votes), past polls