Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all. I find this to mind boggling to provide my own sample code, no idea where to even begin. Lets say I have the following array: @my_array = qw/this array is an"; and another array: @my_indexes = wq/0 2 3 1/; as you can see, this 'fixes' the array indexes in order to write "this is an array". but what if i write a little extra code to randomize the order of the first array, how would i programmatically update the indexes in the @my_indexes array?

Replies are listed 'Best First'.
Re: keep track of array indexes
by 1nickt (Canon) on Jan 02, 2016 at 18:04 UTC

    You don't say what you are really trying to do, but would you not be better served with a hash (aka "associative array")?

    #!/usr/bin/perl use strict; use warnings; my %bits = ( 4 => 'string', 1 => 'this', 3 => 'my', 2 => 'is', ); print join ' ', map $bits{ $_ }, 1 .. 4;
    Output:
    this is my string

    The way forward always starts with a minimal test.

      Or, slightly differently:

      c:\@Work\Perl>perl -wMstrict -le "my @words = qw/this a sentence is/; my %dict = map { $_ => $words[$_] } 0 .. $#words; ;; my @order = (0, 3, 1, 2); print join ' ', map $dict{$_}, @order; " this is a sentence


      Give a man a fish:  <%-{-{-{-<

        thanks.. interesting method. But the ultimate question is, if the order of @words is randomized, how would i re-order @order so that it still produces "this is a sentence" ? pseudo code:
        @words = "this is my sentence" @order = 0, 3, 1, 2 print @order randomize(@words) @order = 2,1,0,3 randomize(@words) @order = 1,0,3,2
        the code is somehow keeping track of changes in the @words array and updating the @order array.
      hmm yes, hash seems a better idea :) thanks, that totally skipped my mind
Re: keep track of array indexes
by GrandFather (Saint) on Jan 02, 2016 at 21:47 UTC

    As a general thing, don't keep parallel data structures. Instead keep one data structure of items where each item has all the related parts. In this case an array of array pairs or an array of hashes:

    use strict; use warnings; my @dataA = ( ['this', 0], ['array', 2], ['is', 3], ['an', 1], ); my @dataH = ( {word => 'this', index => 0}, {word => 'array', index => 2}, {word => 'is', index => 3}, {word => 'an', index => 1}, ); print "$_->[0] " for sort {$a->[1] <=> $b->[1]} @dataA; print "\n"; print "$_->{word} " for sort {$a->{index} <=> $b->{index}} @dataH;

    fits the bill. The hashes version looks like overkill, but has the advantage that the code tends to be self documenting because you access the fields by name rather than by index.

    Premature optimization is the root of all job security
Re: keep track of array indexes
by oiskuu (Hermit) on Jan 03, 2016 at 00:31 UTC

    Nobody did mention array slices, so I naturally couldn't resist fixing the omission. In truth, the whole setup feels like a self-study exercise in slicing and permutations.

    In realistic program code, once you do have indices at hand (in other words, a mapping), there's usually no need to rearrange the actual data. Indirection can be used instead: $data[ $mapping[$i] ]. Nevertheless, it's been a somewhat fun exercise.

      # First of all, keep in mind that keys does not only work on hashes:
      # using it on arrays will yield their list of indices.

      This behavior was introduced with Perl version 5.12.


      Give a man a fish:  <%-{-{-{-<

      wow, spot on!