Question

Suppose I have two arrays that look like this:

('1', '6', '8', '4', '5')
('a', 'c', 'd', 'f', 'w')

I want to sort the first array, and the order of elements in the second array should change in the same way as the first array, so the order of the two becomes as follows:

('1', '4', '5', '6', '8')
('a', 'f', 'w', 'c', 'd')

Any ideas of how to do that in Perl?

Was it helpful?

Solution

You need to sort the indices into the array. Like this

use strict;
use warnings;

my @aa = qw/ 1 6 8 4 5 /;
my @bb = qw/ a c d f w /;

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

@aa = @aa[@idx];
@bb = @bb[@idx];

print "@aa\n";
print "@bb\n";

output

1 4 5 6 8
a f w c d

OTHER TIPS

You could use a hash. Use values from the first array as keys to values taken from the second array. Then just do a foreach my $key ( sort keys %the_hash) { do stuff }. If the key values are not unique then using a hash of arrays and pushing the values into the hash works.

#! perl 
use strict;
use warnings;

my @key_data = ('1', '6', '8', '4', '5', '4', '5');
my @val_data = ('a', 'c', 'd', 'f', 'w', 'z', 'w');

my %the_hash;

for ( my $ii=0; $ii<=$#key_data; $ii++) {
    push @{$the_hash{$key_data[$ii]}}, $val_data[$ii];
}

for my $key ( sort keys %the_hash ) {
    print "key $key\n";
    foreach my $val ( @{$the_hash{$key}} ) {
        print "        $val\n";
    }
}

Borodin's answer is an excellent and most Perlish response to your question. It does occur to me that the structure of your data suggests that a hash might be of use, so here is an example of relating the data via a hash and sorting that way.

use strict;
use warnings;
use List::MoreUtils qw(mesh);

my @aa = qw/ 1 6 8 4 5 /;
my @bb = qw/ a c d f w /;

my %x = mesh @aa, @bb;
print join(" ", sort keys %x), "\n";
print join(" ", @x{sort keys %x}), "\n";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top