Velocity Reviews > Perl > Sorting Hash by Value and Key

# Sorting Hash by Value and Key

vunet.us@gmail.com
Guest
Posts: n/a

 05-17-2007
Could someone show how to sort my hash by values (primary sorting) and
then by key for the same values:

0 => 70,
1 => 50,
6 => 90,
5 => 90,
4 => 90,
);

I want to see:
1 => 50
0 => 70
4 => 90
5 => 90
6 => 90

Thank you

Michele Dondi
Guest
Posts: n/a

 05-17-2007
On 17 May 2007 06:57:20 -0700, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>Could someone show how to sort my hash by values (primary sorting) and
>then by key for the same values:

You can't sort a *hash*. I suppose you want to sort its keys(). Don't
you?

> 0 => 70,
> 1 => 50,
> 6 => 90,
> 5 => 90,
> 4 => 90,
>);
>
>I want to see:
> 1 => 50

A hash is intrinsically unsorted. Get a list of arrayrefs instead.

> 0 => 70

Are you sure you want a hash, anyway? Those keys seem to better suited
for a regular array.

> 4 => 90
> 5 => 90
> 6 => 90

What have you tried thus far? Well, let's spoon-feed you anyway:

my @sorted=sort {\$a->[1] <=> \$b->[1] or \$a->[0] <=> \$b->[0]}

Michele
--
{\$_=pack'B8'x25,unpack'A8'x32,\$a^=sub{pop^pop}->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

Charlton Wilbur
Guest
Posts: n/a

 05-17-2007
>>>>> "v" == vunet us <(E-Mail Removed)> writes:

v> Could someone show how to sort my hash by values (primary
v> sorting) and then by key for the same values:

Because of the way hashes are represented internally, it is
inefficient to maintain them in a sorted order. In other words, you
can't sort a hash. (You can in other languages, yes. If you want
them, you know where to find them.)

What you *can* do is sort a list of hash keys based on the values they
have in a particular hash. See perldoc perlfaq4 under "How do I sort
a hash (optionally by value instead of key)?"

Charlton

--
Charlton Wilbur
(E-Mail Removed)

Mirco Wahab
Guest
Posts: n/a

 05-17-2007
(E-Mail Removed) wrote:
> Could someone show how to sort my hash by values (primary sorting) and
> then by key for the same values:
>
> 0 => 70,
> 1 => 50,
> 6 => 90,
> 5 => 90,
> 4 => 90,
> );
>
> I want to see:
> 1 => 50
> 0 => 70
> 4 => 90
> 5 => 90
> 6 => 90

In addition to the solutions and hints given
already by Michele and Charlton, you could
simply construct another hash which holds
your sort criteria as the 'key', like

0 => 70, 1 => 50,
6 => 90, 5 => 90,
4 => 90 );

print "\$hsort{\$_} \$grades{ \$hsort{\$_} }\n" for sort keys %hsort;

more another solutions of course possible.

Regards

M.

vunet.us@gmail.com
Guest
Posts: n/a

 05-17-2007
spoon-feeding did not work for me. this is my first perl file but i do
try hard anyway. Micro's solution did not sort right (for me) and
Michele's solution i cannot print.
anyway, my goal is (after your feedback) to sort all values and then
sort only thoses keys whose values are the same. example:

0 => 1,
7 => 2,
6 => 3,
5 => 4,
8 => 5,
9 => 6, _______<<
1 => 7,
2 => 7,
3 => 7,
4 => 7,
);

PS: YES, I need to print, not sort a hash itself.
Thanks

Mirco Wahab
Guest
Posts: n/a

 05-17-2007
(E-Mail Removed) wrote:
> spoon-feeding did not work for me. this is my first perl file but i do
> try hard anyway. Micro's solution did not sort right (for me) and
> Michele's solution i cannot print.
> anyway, my goal is (after your feedback) to sort all values and then
> sort only thoses keys whose values are the same. example:

OK, so you want a numerical sort on the values and
then (if equal) a numerical sort on the keys?

You need to employ an extra array of the keys combined
with a sort function, which does what you want, like

...

0 => 1,
9 => 6,
1 => 7,
2 => 7,
3 => 7,
7 => 2,
6 => 3,
5 => 4,
8 => 5,
4 => 7 );

my @hsort =
map \$_,

print "\$_ => \$grades{\$_}\n" for @hsort;

...

In Perl, you have to look hard if your comparison
compares strings (characters) or numeric values.

Regards

Mirco

Mirco Wahab
Guest
Posts: n/a

 05-17-2007
Mirco Wahab wrote:
> my @hsort =
> map \$_,

WTF did I smoke here

the line

> map \$_,

is of course superfluous

Sorry,

M.

vunet.us@gmail.com
Guest
Posts: n/a

 05-17-2007
On May 17, 2:36 pm, Mirco Wahab <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > spoon-feeding did not work for me. this is my first perl file but i do
> > try hard anyway. Micro's solution did not sort right (for me) and
> > Michele's solution i cannot print.
> > anyway, my goal is (after your feedback) to sort all values and then
> > sort only thoses keys whose values are the same. example:

>
> OK, so you want a numerical sort on the values and
> then (if equal) a numerical sort on the keys?
>
> You need to employ an extra array of the keys combined
> with a sort function, which does what you want, like
>
> ...
>
> 0 => 1,
> 9 => 6,
> 1 => 7,
> 2 => 7,
> 3 => 7,
> 7 => 2,
> 6 => 3,
> 5 => 4,
> 8 => 5,
> 4 => 7 );
>
> my @hsort =
> map \$_,
>
> print "\$_ => \$grades{\$_}\n" for @hsort;
>
> ...
>
> In Perl, you have to look hard if your comparison
> compares strings (characters) or numeric values.
>
> Regards
>
> Mirco

Ideal, thanks

Michele Dondi
Guest
Posts: n/a

 05-17-2007
On Thu, 17 May 2007 21:04:33 +0200, Mirco Wahab <(E-Mail Removed)>
wrote:

>WTF did I smoke here
>
>the line
>
> > map \$_,

>
>is of course superfluous

STS? (Schwartzian Transform Syndrome?)

Kinda reminds me of when I discovered the calculus of residues. I was
so fond of it that at some time I found myself applying it to an
integral which, after the work was done... I realized was a trivial
one!

Michele
--
{\$_=pack'B8'x25,unpack'A8'x32,\$a^=sub{pop^pop}->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

Martien verbruggen
Guest
Posts: n/a

 05-17-2007
On 17 May 2007 06:57:20 -0700,
(E-Mail Removed) <(E-Mail Removed)> wrote:
> Could someone show how to sort my hash by values (primary sorting) and
> then by key for the same values:

have a look in the FAQ, section 4, as that answers your question:

How do I sort a hash (optionally by value instead of key)?

and also

How do I sort an array by (anything)?

This FAQ also refers to the 'far more than you ever wanted to know'
document on sorting at http://www.perl.com/CPAN/doc/FMTEYEWTK/sort.html

Martien
--
|
Martien Verbruggen | "In a world without fences,
| who needs Gates?"
|