Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Sorting on Nested Element

by dsb (Chaplain)
on Sep 30, 2011 at 16:23 UTC ( #928852=perlquestion: print w/replies, xml ) Need Help??
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 (Pope) 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}} ];

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://928852]
Approved by lidden
Front-paged by toolic
[thepkd]: Hey 1nickt sorry man. What
[GotToBTru]: a ref too far ;)
[thepkd]: Yes this is my first time in cb. Trying to work my way around.
[JohnCub]: "A ref too far" would make a good title for anyone's perl memoirs
[thepkd]: Anyways it works with $aohoaoh[0]->{'foo '}[0]->{'bar'}
[GotToBTru]: "I did it my $way"
[JohnCub]: I hope $way isn't a hashref. ;)
[GotToBTru]: many times i've been told I made a real hash of thiings

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (12)
As of 2016-12-06 13:47 GMT
Find Nodes?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:

    Results (105 votes). Check out past polls.