JGG
JGG

Reputation: 314

Perl - How to sort array values by a given order?

In that How to sort a list with a given order?

We have discussed how to sort a list based on a given order using map and $_. Today I have another question.

I have the same orderby:

my @orderby = ( 'car', 'boat', 'chicken', 'cat', 'dog', 'mouse');
# or if it's better to the code:
my %orderby = ( 'car' => 0, 
                'boat' => 1, 
                'chicken' => 2, 
                'cat' => 3, 
                'dog' => 4, 
                'mouse' => 5); 

And now I have the following that need to be ordered by orderby:

print Dumper \%toys;
$VAR = {
         'animals'  =>  [
                          [
                            'feather', 'cluck-2', 'chicken', 'white'
                          ],
                          [
                            'bald', 'bark', 'dog', 'black stripes'
                          ],
                          [
                            'feather', 'cluck-2', 'chicken', 'white'
                          ]
                        ],
         'notanima' =>  [
                          [
                            'paited', 'motor', 'boat', 'red'
                          ],
                          [
                            'painted', 'motor', 'car', 'blue on top'
                          ]
                        ]
       };

The code need to sort using the 3 column based on orderby. You need to use the same ordery for animals and notanima. After the rearrange, the $VAR will be:

$VAR = {
         'animals'  =>  [
                          [
                            'feather', 'cluck-2', 'chicken', 'white'
                          ],
                          [
                            'feather', 'cluck-2', 'chicken', 'white'
                          ],
                          [
                            'bald', 'bark', 'dog', 'black stripes'
                          ]
                        ],
         'notanima' =>  [
                          [
                            'painted', 'motor', 'car', 'blue on top'
                          ],
                          [
                            'paited', 'motor', 'boat', 'red'
                          ]
                        ]
       }; 
order %toys{key} by orderby;

I have tried to change the map solution that @ikegami provided

my %counts; ++$counts{$_} for @list;
my @sorted = map { ($_) x ($counts{$_}||0) } @orderby;

but I didn't have success. Do you guys have any ideas how can I achieve this objective?

Thx in advance!

Update!
I was trying to use the suggestion from ikegami, I have done this:

# that first foreach will give one ARRAY for animals and one ARRAY for notanima
foreach my $key (keys %toys)
{
   # that one will give me access to the ARRAY referenced by the $key.
   foreach my $toy_ref ($toys{$key})
   {
       my %orderby = map {$orderby[$_] => $_} 0..$#orderby;
       my @sorted = sort { $orderby{$a} <=> $orderby{$b} } @{$toy_ref};
       # my @sorted = sort { $orderby{$a} <=> $orderby{$b} } $toy_ref;
       print Dumper @sorted;
   }
}

First, this gives me the warning:

Use of uninitialized value in numeric comparison (<=>) at....

And the result of the sort for notanima (I will ignore animals, so the post will not be so big):

$VAR1 = [
         'paited', 'motor', 'boat', 'red'
       ];
$VAR2 = [
         'painted', 'motor', 'car', 'blue on top'
       ];

Based on orderby, the print order need to be:

$VAR1 = [
         'painted', 'motor', 'car', 'blue on top'
       ];
$VAR2 = [
         'paited', 'motor', 'boat', 'red'
       ];

Car need to come first. What I have done wrong?

Upvotes: 1

Views: 195

Answers (1)

ikegami
ikegami

Reputation: 385655

So you have 6 arrays to sort, so you'll need six calls to sort.

  1. For each element of %toys,
    1. For each element of the array referenced by that element of %toys,
      1. Sort the referenced array as previously shown.

And please don't use the solution that was labeled "messes with people's mind".

Upvotes: 1

Related Questions