http://www.perlmonks.org?node_id=928852

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

Hello all, I'm trying to sort on a nested key value. Given a data structure that looks like this:
$data = { Elements => { AlphaKey => { Name => 'Foo', Priority => 2, OtherVal => 'randomthings' }, BetaKey => { Name => 'Bar', Priority => 1, OtherVal => 'morerandomthings' }, }};
I want to process them in a sorted order based on the priority value. I'm trying to just turn the hashref into an arrayref, so that it winds up looking like:
$sorted = [ { Name => 'Bar', Priority => 1 OtherVal => 'morerandomthings' }, { Name => 'Foo', Priority => 2, OtherVal => 'randomthings' }, ];
It's easy enough to get a sorted list of priorities:
my @pri = sort { $a <=> $b } map { $data->{Elements}{$_}->{priority} } + keys %{$data->{Elements}};
I'm lost on how to build an arrayref-based structure from there. I'm not even sure i'm going down the right path now that I'm typing it out. Thoughts?

Replies are listed 'Best First'.
Re: Sorting on Nested Element
by BrowserUk (Patriarch) on Sep 30, 2011 at 16:37 UTC
    I'm lost on how to build an arrayref-based structure from there.

    You don't need to. If you create a list of keys to the original hash in your required order:

    my @keysInPriorityOrder = sort { $data->{Elements}{$a}->{priority} <=> $data->{Elements}{$b}->{priority} } keys %{ $data->{Elements} };

    Then to process the sub hashes in that order:

    for my $key ( @keysInPriorityOrder ) { my $subhash = $data->{Elements}{ $key }; print $subhash->{ $_ } for qw[ Priority Name OtherVal ]; }

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Sorting on Nested Element
by TomDLux (Vicar) on Sep 30, 2011 at 18:34 UTC
    push @$sorted, $data->{Elements}{$_} for @pri;

    Some people recommend using curly braces with dual sigils. I certainly do that with more complicated ones, but I feels it's simple enough when you say, "Take this scalar and access the array ( or hash ) it references".

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Re: Sorting on Nested Element
by Anonymous Monk on Sep 30, 2011 at 20:48 UTC

    Since keys are not needed:

    my $sorted = [ sort {$a->{Priority} <=> $b->{Priority}} values %{$data->{Elements}} ];