sorting by multiple criterias (sub-sorting)

T

Tom Kirchner

hello!

Im currently writing on a part of a program where there is an
array of hash-refs holding data. and I want to sort these
array-elements (the hash-refs) by a first criteria and then
another one. E.g. If each hash would be something like:

@array = (
{ 'name' => 'dan', 'age' => '12', 'shoesize' => '34' },
{ 'name' => 'tom', 'age' => '19', 'shoesize' => '56' },
{ 'name' => 'tom', 'age' => '23', 'shoesize' => '43' },
{ 'name' => 'frank', 'age' => '42', 'shoesize' => '24' },
# ...
);

what I want is: sorting first by 'name' and then, when there
are multiple records with the same name, sorting this (sub)group
by their 'age' and if there are records with the same
name and same age, sorting these by their shoesize.
This is just an example and the real thing is much more
complex, but I need a general idea of how this could be done.

thanks
tom
 
C

Cognition Peon

9:28am, IP packets from Tom Kirchner delivered:
hello!

Im currently writing on a part of a program where there is an
array of hash-refs holding data. and I want to sort these
array-elements (the hash-refs) by a first criteria and then
another one. E.g. If each hash would be something like:

@array = (
{ 'name' => 'dan', 'age' => '12', 'shoesize' => '34' },
{ 'name' => 'tom', 'age' => '19', 'shoesize' => '56' },
{ 'name' => 'tom', 'age' => '23', 'shoesize' => '43' },
{ 'name' => 'frank', 'age' => '42', 'shoesize' => '24' },
# ...
);

sub sort_func {
$a->{name} cmp $b->{name} ||
$a->{age} <=> $b->{age} ||
$a->{shoesize} <=> $b->{shoesize}
}

@sorted_array = sort sort_func (@array);
 
S

Steve Grazzini

Tom Kirchner said:
Im currently writing on a part of a program where there is an
array of hash-refs holding data. and I want to sort these
array-elements (the hash-refs) by a first criteria and then
another one.

There are two FAQs dealing with this topic:

% perldoc -q sort
E.g. If each hash would be something like:

@array = (
{ 'name' => 'dan', 'age' => '12', 'shoesize' => '34' },

Just a style nit:

{ name => 'dan', age => 12, shoesize => 34 },
{ 'name' => 'tom', 'age' => '19', 'shoesize' => '56' },
{ 'name' => 'tom', 'age' => '23', 'shoesize' => '43' },
{ 'name' => 'frank', 'age' => '42', 'shoesize' => '24' },
# ...
);

what I want is: sorting first by 'name' and then, when there
are multiple records with the same name, sorting this (sub)group
by their 'age' and if there are records with the same
name and same age, sorting these by their shoesize.

Quoting from "How do I sort an array by (anything)?"

If you need to sort on several fields, the following paradigm
is useful.

@sorted = sort { field1($a) <=> field1($b) ||
field2($a) cmp field2($b) ||
field3($a) cmp field3($b)
} @data;

This works because when two elements of the input list are
equal, the <=> and cmp operators will return zero (and the
sub will fall through to the next comparison).

To adapt it to your example, just substitute hash lookups for
the subroutine call.

@sorted = sort { $a->{name} cmp $b->{name} ||
$a->{age} <=> $b->{age} ...
 
M

Michael Budash

Cognition Peon said:
9:28am, IP packets from Tom Kirchner delivered:


sub sort_func {
$a->{name} cmp $b->{name} ||
$a->{age} <=> $b->{age} ||
$a->{shoesize} <=> $b->{shoesize}
}

@sorted_array = sort sort_func (@array);

of course, the o.p. does not _have_ to use a subroutine:

@sorted_array = sort {
$a->{name} cmp $b->{name} ||
$a->{age} <=> $b->{age} ||
$a->{shoesize} <=> $b->{shoesize}
} @array;
 

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

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top