Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sort an array according to elements of a second array

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?

like image 573
Abdel Avatar asked May 06 '13 11:05

Abdel


People also ask

How do you sort an array with two elements?

Step 1 : Here we can take two pointers type0 (for element 0) starting from beginning (index = 0) and type1 (for element 1) starting from end index. Step 2: We intend to put 1 to the right side of the array. Once we have done this then 0 will definitely towards left side of array to achieve this we do following.

How do you sort an array according to another array in C++?

qsort(array1,6, sizeof(int), compare); The point is how to make the compare function for order array1 based on array2. It is not possible to use std library data structures, it must be done directly in the array pointers.

How do you sort an array in ascending order based on the ranks of each element which is in the another array?

The short answer is: std::sort . The basic idea is to create a std::vector<std::pair<int,int>> and then simply sort that via std::sort . The rest of the code is about copying the values and ranks into that vector and copying the values out of it after sorting.


3 Answers

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
like image 54
Borodin Avatar answered Oct 11 '22 07:10

Borodin


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";
    }
}
like image 42
AdrianHHH Avatar answered Oct 11 '22 08:10

AdrianHHH


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";
like image 44
Bill Ruppert Avatar answered Oct 11 '22 06:10

Bill Ruppert