Search code examples
perlloopsround-robin

Perl - Roundrobin through hash of arrays


my %aggrs_by_node = (
    node1 => ['a1_1','a1_2'],
    node2 => ['a2_1','a2_2','a2_3'],
    hello => ['ah_1','ah_2','ah_3'],
    node3 => ['a3_1','a3_2','a3_3','a3_4'],
);

Anyone have any suggestions for how I could round-robin through all the arrays elements in this hash while avoiding the key hello?

Iteration 1 = a1_1
Iteration 2 = a2_1
Iteration 3 = a3_1
Iteration 4 = a1_2
Iteration 5 = a2_2
Iteration 6 = a3_2
Iteration 7 = a1_1
Iteration 8 = a2_3

etc...


Solution

  • This short program does what you ask. It keeps a hash of indices into each array.

    I have used a separate sorted list of the hash keys in array @keys because taking them directly from the hash will result in an unpredictable order, and it looks like you need the output in a specific order.

    use strict;
    use warnings;
    
    my %aggrs_by_node = (
      node1 => ['a1_1','a1_2'],
      node2 => ['a2_1','a2_2','a2_3'],
      hello => ['ah_1','ah_2','ah_3'],
      node3 => ['a3_1','a3_2','a3_3','a3_4'],
    );
    
    my %indices = map { $_ => 0 } keys %aggrs_by_node;
    delete $indices{hello};
    my @keys = sort keys %indices;
    
    for my $iter (1 .. 20) {
      my $key = $keys[($iter - 1) % @keys];
      my $val = $aggrs_by_node{$key}[$indices{$key}];
      $indices{$key} = ($indices{$key} + 1) % @{ $aggrs_by_node{$key} };
      printf "Iteration %d = %s\n", $iter, $val;
    }
    

    output

    Iteration  1 = a1_1
    Iteration  2 = a2_1
    Iteration  3 = a3_1
    Iteration  4 = a1_2
    Iteration  5 = a2_2
    Iteration  6 = a3_2
    Iteration  7 = a1_1
    Iteration  8 = a2_3
    Iteration  9 = a3_3
    Iteration 10 = a1_2
    Iteration 11 = a2_1
    Iteration 12 = a3_4
    Iteration 13 = a1_1
    Iteration 14 = a2_2
    Iteration 15 = a3_1
    Iteration 16 = a1_2
    Iteration 17 = a2_3
    Iteration 18 = a3_2
    Iteration 19 = a1_1
    Iteration 20 = a2_1