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

Fellow Monasterians,

I had no problem grepping a straight AoH, but I can't figure out how to do it with references. Googled and Supersearched to little avail (learned lots of other stuff, though ;^). What am I not getting?

my $AoHref = [ { name => "barney", age => "43" }, { name => "fred", age => "44" }, { name => "wilma", age => "42" } ]; my $newAoH = grep { !($_->{'name'} eq "fred") } $AoHref; print Dumper ($newAoH);

I'm sure the problem is in how I dereference in the grep statement. Tried things like:

my $newAoH = grep { !({$_->{'name'}} eq "fred") } $AoHref;

...but nada. Thanks.


—Brad
"Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton

Replies are listed 'Best First'.
Re: Grep and AoH references
by davido (Cardinal) on Dec 30, 2004 at 16:43 UTC
    my $newAoH = [ grep { !( $_->{name} eq 'fred' ) } @{$AoHref} ];

    You have to dereference $AoHref to look like an array. That's the @{$AoHref} part. And you have to create a new arrayref to feed to $newAoH. That's the [ ......... ] part... unless you really meant to feed @newAoH (a proper array), instead of $newAoH (a reference to an array).


    Dave

      Thanks davido. Worked like a charm. And thanks for the explanation.


      —Brad
      "Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton
Re: Grep and AoH references
by Roy Johnson (Monsignor) on Dec 30, 2004 at 16:42 UTC
    Grep wants an array for its second argument. Dereference your AoHref:
    my $newAoH = [grep { !($_->{'name'} eq "fred") } @$AoHref];
    Update: I was too hasty and only fixed the dereference problem. Obviously, to create a new AoH, you have to actually create the reference. So I've put the brackets on the expression.

    Caution: Contents may have been coded under pressure.

      Actually grep want a list following its first argument. The reason the code doesnt throw a wobbly is that a reference to an array is a list of one element (the reference). By dereferencing $AoHref you get a different list, that being the contents of the array. A subtle but important distinction (that lots of folks around here love to harp on about, like me :-)

      Also the code as posted is wrong. Grep returns a list, so if you assign to a scalar like you are you get the count of objects that passed the filter test, not the list of objects. The code should look like my @grepped=grep ...

      ---
      alter ego of demerphq

      I tried that but Data::Dumper returned "2".


      —Brad
      "Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton
Re: Grep and AoH references
by trammell (Priest) on Dec 30, 2004 at 17:04 UTC
    There's always:
    @$AoHref = grep { !($_->{'name'} eq "fred") } @$AoHref;
    if you don't mind clobbering your original data. Or similarly:
    my @newAoH = grep { !($_->{'name'} eq "fred") } @$AoHref; my $newAoHref = \@newAoH; ...