http://qs321.pair.com?node_id=746626


in reply to Re^6: (Mis)Understanding "works"
in thread (Mis)Understanding grep...eq $_

Update:posted this my mistake at wrong reply level. I am agreeing with Tye and showing an example of how to use grep on "arrays".

I don't know exactly what is meant by "array" in a Perl context. There are lists and lists of lists of lists(LoL) and of course lists of lists of lists(LoLoL), Lists of Hashes (LoH), etc. grep works great on all these things! If you mean that a LoL is an "array" then here is one example of how to use grep on something like that:

#!/usr/bin/perl -w use strict; #remove "rows" that don't have a value greater than 75 my $value =75; my $rLoL = [ [78,43,87], [64,73,72], [99], [65,67,71] ]; @$rLoL = grep { (grep {$_ > $value}@$_)>=1}@$rLoL; foreach my $ref (@$rLoL) { print "@$ref\n"; } #prints #78 43 87 #99 #the inside grep above is used in a scalar context. #It basically says "do we want to keep this list or not?" #outside grep passes list ref to output based upon that #true/false decision. #grep{} works with anything that can be reduced to a #yes/no question #@LoH = grep{keys (%_) > 2}@LoH #removes hashes from List of Hashes that have fewer #than 3 keys.

Replies are listed 'Best First'.
Re^8: (Mis)Understanding "works"
by Marshall (Canon) on Feb 26, 2009 at 21:47 UTC
    Grep can be used in very complex ways. I'm posting yet another example of how to use grep{} on complex structures. A grep within a grep is just fine as above post shows, but it is also possible to use map{} within a grep.

    Basically when you are thinking about filtering something out, think about grep. Map{} is used to change or transform something and often folks get these ideas confused. Also many folks think that Perl grep is like Unix grep with regex'es. Perl grep is WAY more powerful! The code below operates on a list of matrices and deletes those which have fewer than some minimum number of total elements.

    #!/usr/bin/perl -w use strict; use Data::Dumper; my $min_elements = 11; my $rLoLoL =[ [ [78,43,87], [64,73,72], [99], [65,67,71] ], [ [1,2,3], [4,5], [6,7],[8, 9, 10, 11] ], ]; @$rLoLoL = grep { (my @elements = map{@$_}@$_)>= $min_elements }@$rLoLoL; #some explanation ...most folks posting in this thread have #thousands of posts and are experienced..but perhaps this will #help others...although most folks don't go down this deep #into the thread... #the @$rLoLoL gets the list of references to matrices, the #list of lists of lists (LoLoL). # in: ...map{@$_}@$_), this last @$_ gets List of List's # the map{} takes each one of these and "flattens the matrix # out", what goes into @elements is like (78,43,87,64,73,72,99,65,67,7 +1). # print Dumper ($rLoLoL); #the first "matrix" with 10 total elements has been removed... __END__ Prints: $VAR1 = [ [ [ 1, 2, 3 ], [ 4, 5 ], [ 6, 7 ], [ 8, 9, 10, 11 ] ] ];