in reply to Re^4: Is there better way to delete dups in an AoH?
in thread Is there better way to delete dups in an AoH?

I think you want to have your last map return one 2-element hash ref for each unique key. Instead, you're creating two 1-element hash refs, and returning only the second one.
my %uniq = map { ($_->{page} => 1, $_->{chap} => 1) } @$AoH; @$AoH = map { { page => $_ , chap=>$_ } } keys %uniq;

The PerlMonk tr/// Advocate

Replies are listed 'Best First'.
Re^6: Is there better way to delete dups in an AoH?
by bradcathey (Prior) on Jun 06, 2004 at 23:53 UTC
    Thanks Roy_Johnson! Before I posted I tried it exactly as you had it, but without the parens to make it an element. Just didn't see it. I love this place.

    —Brad
    "A little yeast leavens the whole dough."
Re^6: Is there better way to delete dups in an AoH?
by bradcathey (Prior) on Jun 08, 2004 at 02:37 UTC
    Roy Johnson, I still hope you're watching this thread. Your solution works great if the values of both keys in the array element are the same:
    page=>'fall', chap=>'fall'
    BUT, what if they are different:
    my $AoH = [ { page => 'main', chap => 'About'}, { page => 'main', chap => 'Contact'}, { page => 'main', chap => 'About'}, { page => 'sub', chap => 'About'}, { page => 'sub', chap => 'Contact'} ]; my %uniq = map { ($_->{page} => 1, $_->{chap} => 1) } @$AoH; @$AoH = map { { page => $_ , chap=>$_ } } keys %uniq; print Dumper ($AoH);
    Which prints:
    $VAR1 = [ { 'chap' => 'Contact', 'page' => 'Contact' }, { 'chap' => 'About', 'page' => 'About' }, { 'chap' => 'sub', 'page' => 'sub' }, { 'chap' => 'main', 'page' => 'main' } ];
    I want to end up with:
    $VAR1 = [ { 'page' => 'main', 'chap' => 'About' }, { 'page' => 'main', 'chap' => 'Contact' }, { 'page' => 'sub', 'chap' => 'About' }, { 'page' => 'sub', 'chap' => 'Contact' } ];
    eliminating that dupe element of:
    'page' => 'main', 'chap' => 'About'
    I've stared at it for an hour and am bewildered. Ideas? Thanks.

    —Brad
    "A little yeast leavens the whole dough."
      Yes, it does call for a modified approach. What you want is a way to find each unique combination of two words, but hash keys have to be simple scalars. To uniquify a combination of two strings, we'll need a two-level hash. This relies on the fact that you know the keys of your hash (which makes it effectively a simple array).
      my %uniq; for (@$AoH) { $uniq{$_->{page}}{$_->{chap}} = 1; } @$AoH = map { my $k = $_; map { {page => $k , chap=>$_} } keys %{$uniq{$k}}; } keys %uniq;
      The principle is the same as before: make a hash entry for each item, then find all the unique keys and rebuild the original AoH from that. The only difference is that we're going two levels deep.

      The PerlMonk tr/// Advocate
        Magical! Roy Johnson, thanks for your excellent solution. Honestly, I'm not sure how it works, but I promise to study it."

        —Brad
        "A little yeast leavens the whole dough."