Sorting Hash by Value and Key

V

vunet.us

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

%grades = (
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
 
M

Michele Dondi

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?
%grades = (
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.

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]}
map [$_ => $grades{$_}], keys %grades;


Michele
 
C

Charlton Wilbur

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
 
M

Mirco Wahab

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

%grades = (
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


my %grades = (
0 => 70, 1 => 50,
6 => 90, 5 => 90,
4 => 90 );

my %hsort= map +($grades{$_}.$_,$_), keys %grades;

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



more another solutions of course possible.

Regards

M.
 
V

vunet.us

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:

%grades = (
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
 
M

Mirco Wahab

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

...

my %grades = (
0 => 1,
9 => 6,
1 => 7,
2 => 7,
3 => 7,
7 => 2,
6 => 3,
5 => 4,
8 => 5,
4 => 7 );

my @hsort =
sort { $grades{$a} <=> $grades{$b} || $a <=> $b }
map $_,
keys %grades;

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

...


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

Regards

Mirco
 
V

vunet.us

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

...

my %grades = (
0 => 1,
9 => 6,
1 => 7,
2 => 7,
3 => 7,
7 => 2,
6 => 3,
5 => 4,
8 => 5,
4 => 7 );

my @hsort =
sort { $grades{$a} <=> $grades{$b} || $a <=> $b }
map $_,
keys %grades;

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
 
M

Michele Dondi

WTF did I smoke here :)

the line


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
 
M

Martien verbruggen

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

In addition to the answers you already have, you should probably also
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top