#### Do you have a question? Post it now! No Registration Necessary. Now with pictures!

**posted on**

May 5, 2005, 7:22 pm

> Brett wrote:

> > I have two arrays and i wish to sort the first one numerically, but

> > after sorting, I would like the second array to be in the same

> > matching order as the first array.

> >

> > ie.

> >

> > @l1=;

> > @l2=;

> >

> > @l1 = sort {$a <=> $b} (@l1); # sort list @l1 to be

> >

> > # do something to @l2 to make order (preserving the

> > original mapping with the first list)

> >

> > There's probably an easy way to do this that i'm not aware of.

>

> Indeed, there is: use a data structure that matches your problem better.

> Instead of having a pair of unrelated arrays use a single array of pairs.

> And then sort that single array by the value of the first component of

each

> pair.

>

> jue

I'm new to this, and tried to give it a go.

use Class::Struct;

struct ID =>

{

number => '$',

name => '$',

};

my @IDs = ID->new();

#fill data...

@IDs = sort {$a->number <=> $b->number} (@IDs); # numeric sort on number

but that failed to sort the list as i expected. How can i use sort on a

structure to do

what I want?

## Re: sorting a structure

On Thu, 5 May 2005, Brett wrote:

> > Brett wrote:

> > > I have two arrays and i wish to sort the first one numerically, but

> > > after sorting, I would like the second array to be in the same

> > > matching order as the first array.

> > >

> > > ie.

> > >

> > > @l1=;

> > > @l2=;

> > >

> > > @l1 = sort {$a <=> $b} (@l1); # sort list @l1 to be

> > >

> > > # do something to @l2 to make order (preserving the

> > > original mapping with the first list)

> > >

> > > There's probably an easy way to do this that i'm not aware of.

> >

> > Indeed, there is: use a data structure that matches your problem better.

> > Instead of having a pair of unrelated arrays use a single array of pairs.

> > And then sort that single array by the value of the first component of

> each

> > pair.

> >

> > jue

>

>

> I'm new to this, and tried to give it a go.

>

> use Class::Struct;

Haven't seen anything in your description that requires OO-style

programming.

> struct ID =>

> {

> number => '$',

> name => '$',

> };

>

> my @IDs = ID->new();

> #fill data...

The constructor returns a single item (a blessed reference); I'm not

sure why you would want to store it into an array though.

> @IDs = sort {$a->number <=> $b->number} (@IDs); # numeric sort on number

Are your sorting an array containing just a single item?

> but that failed to sort the list as i expected. How can i use sort on a

> structure to do

> what I want?

I think this is more along the lines of what Jürgen suggested:

use strict;

use warnings;

use List::MoreUtils qw(pairwise);

my @l1 = (3, 1, 2);

my @l2 = qw(a b c);

my @numbers_sorted;

my @letters_mapped;

for my $aref (

sort { $a->[0] <=> $b->[0] }

pairwise { [$a, $b] } @l1, @l2

) {

push @numbers_sorted, $aref->[0];

push @letters_mapped, $aref->[1];

}

--

Hope this helps,

Steven

## Re: sorting a structure

> On Thu, 5 May 2005, Brett wrote:

>

> > > Brett wrote:

> > > > I have two arrays and i wish to sort the first one numerically, but

> > > > after sorting, I would like the second array to be in the same

> > > > matching order as the first array.

[snippage]

> I think this is more along the lines of what Jürgen suggested:

>

> use strict;

> use warnings;

> use List::MoreUtils qw(pairwise);

[presumably correct implementation snipped]

However, regrouping the data structure is not strictly necessary. Indirect

sorting is an age-honored technique of ordering one list according to

another. You first sort a list of indices to the numeric array according

to the values in that array. Then you take the elements of the second

array in sequence of the indices:

my @l1 = qw( 3 1 2);

my @l2 = qw( a b c);

my @l2_sorted = @l2[ sort { $l1[ $a] <=> $l1[ $b] } 0 .. $#l1];

Anno

## Re: sorting a structure

On 5 May 2005, Anno Siegel wrote:

>

> > I think this is more along the lines of what Jürgen suggested:

> >

> > use strict;

> > use warnings;

> > use List::MoreUtils qw(pairwise);

>

> [presumably correct implementation snipped]

>

> However, regrouping the data structure is not strictly necessary. Indirect

> sorting is an age-honored technique of ordering one list according to

> another. You first sort a list of indices to the numeric array according

> to the values in that array. Then you take the elements of the second

> array in sequence of the indices:

>

> my @l1 = qw( 3 1 2);

> my @l2 = qw( a b c);

> my @l2_sorted = @l2[ sort { $l1[ $a] <=> $l1[ $b] } 0 .. $#l1];

>

I like it!

To efficiently generate two sorted arrays, one would presumably save the

sorted indices:

my @sorted_idx = sort { $l1[ $a] <=> $l1[ $b] } 0 .. $#l1 ;

my @l1

___sorted = @l1[ @sorted___idx ];

my @l2

___sorted = @l2[ @sorted___idx ];

Thanks for the tip.

--

Regards,

Steven

## Re: sorting a structure

> On 5 May 2005, Anno Siegel wrote:

>

> >

> > > I think this is more along the lines of what Jürgen suggested:

> > >

> > > use strict;

> > > use warnings;

> > > use List::MoreUtils qw(pairwise);

> >

> > [presumably correct implementation snipped]

> >

> > However, regrouping the data structure is not strictly necessary. Indirect

> > sorting is an age-honored technique of ordering one list according to

> > another. You first sort a list of indices to the numeric array according

> > to the values in that array. Then you take the elements of the second

> > array in sequence of the indices:

> >

> > my @l1 = qw( 3 1 2);

> > my @l2 = qw( a b c);

> > my @l2_sorted = @l2[ sort { $l1[ $a] <=> $l1[ $b] } 0 .. $#l1];

> >

>

>

>

> I like it!

>

> To efficiently generate two sorted arrays, one would presumably save the

> sorted indices:

>

> my @sorted_idx = sort { $l1[ $a] <=> $l1[ $b] } 0 .. $#l1 ;

>

> my @l1_sorted = @l1[ @sorted_idx ];

> my @l2_sorted = @l2[ @sorted_idx ];

Yes, that's when indirect sorting really begins to pay. You sort

only once (n*log n), then re-arrange any number of arrays in linear

time.

Anno

## Re: sorting a structure

> > On 5 May 2005, Anno Siegel wrote:

> >

> > >

> > > > I think this is more along the lines of what Jürgen suggested:

> > > >

> > > > use strict;

> > > > use warnings;

> > > > use List::MoreUtils qw(pairwise);

> > >

> > > [presumably correct implementation snipped]

> > >

> > > However, regrouping the data structure is not strictly necessary.

Indirect

> > > sorting is an age-honored technique of ordering one list according to

> > > another. You first sort a list of indices to the numeric array

according

> > > to the values in that array. Then you take the elements of the second

> > > array in sequence of the indices:

> > >

> > > my @l1 = qw( 3 1 2);

> > > my @l2 = qw( a b c);

> > > my @l2_sorted = @l2[ sort { $l1[ $a] <=> $l1[ $b] } 0 .. $#l1];

> > >

> >

> >

> >

> > I like it!

> >

> > To efficiently generate two sorted arrays, one would presumably save the

> > sorted indices:

> >

> > my @sorted_idx = sort { $l1[ $a] <=> $l1[ $b] } 0 .. $#l1 ;

> >

> > my @l1_sorted = @l1[ @sorted_idx ];

> > my @l2_sorted = @l2[ @sorted_idx ];

>

> Yes, that's when indirect sorting really begins to pay. You sort

> only once (n*log n), then re-arrange any number of arrays in linear

> time.

>

> Anno

Thanks for your help. Thats the answer that I was looking for.

Brett.

#### Site Timeline

- » FAQ 1.3 Which version of Perl should I use?
- — Next thread in » PERL Discussions

- » unpacking SAP data
- — Previous thread in » PERL Discussions

- » s suffix question
- — Newest thread in » PERL Discussions

- » Dell Battery Slice LED codes
- — The site's Newest Thread. Posted in » Laptop Computers Forum