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


in reply to need to sort array of hash

I have a solution, included below.

It is an ugly solution. It is a fragile solution.

This is because you have a horrible data structure[1] and have not fully specified the problem[2]. If you give it data where a "Task*" key has any sibling keys, you will get undefined results because there's no expectation that the correct inner hash will be the first one returned by values.

But, with those caveats:

#!/usr/bin/env perl use strict; use warnings; use 5.010; my $original = [ { 'TaskA' => { 'maruti' => '20', 'honda' => '25', 'zen' => '25', 'hyundai' => '35', 'ford' => '22', 'toyota' => '11' } }, { 'TaskB' => { 'maruti' => '11', 'honda' => '22', 'zen' => '33', 'hyundai' => '33', 'ford' => '24', 'toyota' => '16' } }, { 'TaskC' => { 'maruti' => '12', 'honda' => '22', 'zen' => '33', 'hyundai' => '44', 'ford' => '55', 'toyota' => '66' } } ]; my $sorted = [ sort { (values(%$b))[0]->{hyundai} <=> (values(%$a))[0]->{hyundai} } @$original ]; use Data::Printer; p $sorted;
Output:
\ [ [0] { TaskC { ford 55, honda 22, hyundai 44, maruti 12, toyota 66, zen 33 } }, [1] { TaskA { ford 22, honda 25, hyundai 35, maruti 20, toyota 11, zen 25 } }, [2] { TaskB { ford 24, honda 22, hyundai 33, maruti 11, toyota 16, zen 33 } } ]

[1] The "Task*" layer is superfluous. It really looks like your sub-hashes with the actual data should be stored directly in the outer array, without the intermediate single-key hashes. Any time you think you want a hash with keys named "Foo1", "Foo2", "Foo3"..., odds are you actually want an array, not a hash.

[2] What should be done if one of the intermediate-layer hashes has more than one "Task*" key, or any keys other than the single "Task*" key? (If that's never allowed to happen, then see [1].)