in reply to Sort array + keep associated indexes in other array

Simple, only sort one thing. Maintaining parallel data structures is a real pain, so don't do that. Instead use either an array of arrays or a hash. Consider:

use strict; use warnings; my @items = (["dog", 20], ["desk", 10], ["cow", 150]); print "By name:\n"; print "$_->[0]: $_->[1]\n" for sort {$a->[0] cmp $b->[0]} @items; print "\nBy weight:\n"; print "$_->[0]: $_->[1]\n" for sort {$a->[1] <=> $b->[1]} @items;

and:

use strict; use warnings; my %items = (dog => 20, desk => 10, cow => 150); print "By name:\n"; print "$_: $items{$_}\n" for sort {$a cmp $b} keys %items; print "\nBy weight:\n"; print "$_: $items{$_}\n" for sort {$items{$a} <=> $items{$b}} keys %it +ems;

Both print:

By name: cow: 150 desk: 10 dog: 20 By weight: desk: 10 dog: 20 cow: 150
True laziness is hard work

Replies are listed 'Best First'.
Re^2: Sort array + keep associated indexes in other array
by johnzzz (Initiate) on Mar 28, 2012 at 09:23 UTC
    yes I was thinking that way too, but I'm trying to avoid that solution, because in my script it's not very easy to join those two arrays ( there are variable count of spaces between them during printing, the arrays are filled in different time etc.). That sorting i'm trying to do is the last thing in my script (I will only print it afterwards), so I don't have to worry about maintaining parallel data structures

      In that case, you can zip the arrays together before sorting them, then unzip them afterwards.

      Something like...

      use Data::Dumper; my @array_items = ("dog" ,"desk" ,"cow"); my @array_items_weight = ("20" ,"10", "150"); # zip them together my @combined = map { [$array_items[$_], $array_items_weight[$_]] } 0 .. $#array_items; # sort the zipped array my @sorted = sort { $a->[0] cmp $b->[0] } @combined; # unzip again @array_items = map { $_->[0] } @sorted; @array_items_weight = map { $_->[1] } @sorted; print "\@array_items is now... "; print Dumper \@array_items; print "\@array_items_weight is now... "; print Dumper \@array_items_weight;

      The above produces the following output...

      @array_items is now... $VAR1 = [
                'cow',
                'desk',
                'dog'
              ];
      @array_items_weight is now... $VAR1 = [
                '150',
                '10',
                '20'
              ];
      

      This solution assumes that @array_items and @array_items_weight are equal in length.

      Zipping them together is somewhat ugly code, but with the assistance of List::MoreUtils it can be made more beautiful:

      my @combined = pairwise { [$a, $b] } @array_items, @array_items_weight +;
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'