Problem: Iterate over each array in parallel (in other words, treat each array as a column, and each index as a row). For each row, find the max value among the columns, and report that max along with which column or columns have that value.
One possible solution: I created a subroutine named get_max_and_column_list_per_row(), which is a really awkward name, but it does pretty much exactly what you're asking for:
Pass it a list of array references (a LOL: perllol). The function evaluates each row (each outer index) to find the max value in that row's columns. It also keeps track of which columns that max was found in. It constructs an array in original row order. That array consists of an anonymous hash. The key is that max value found for the given row. The value is an anonymous array of the column numbers that contained that max value. Clear as mud. :)
use Modern::Perl; use List::Util qw( max ); # Build a sample dataset of ten rows of ten columns each, # with random numbers between zero and nine. my @lists = map { [ map { int( rand( 10 ) ) } 1 .. 10 ] } 1 .. 10; # Invoke our dirty little function to get the list # of maxes per row, and columns that hit that max. my @max_indices = get_max_and_column_list_per_row( @lists ); # Print our list out nicely. { local $" = ", "; foreach my $row_index ( 0 .. $#max_indices ) { my ( $max, $columns ) = each %{ $max_indices [ $row_index ] }; say "Row $row_index has a max of $max in column(s) @{$col +umns}"; } } # The ugly function. Accepts a LoL, returns a LoHoL. sub get_max_and_column_list_per_row { my( @arrays ) = @_; # First, find out how many columns we have. my $top_index = max( map $#{$_}, @arrays ); # The rest is a big map{}. return map { my $outer_index = $_; my $current_max = max( @{ $lists[$outer_index] } ); +{ # Anonymous hash constructor. $current_max => [ grep { $lists[$outer_index][$_] == $current_max } 0 .. $top_index ] } # End of anonymous hash constructor. } 0 .. $#lists; }
Sample output:
Row 0 has a max of 9 in column(s) 2, 5 Row 1 has a max of 7 in column(s) 7, 9 Row 2 has a max of 7 in column(s) 6 Row 3 has a max of 9 in column(s) 1 Row 4 has a max of 9 in column(s) 3 Row 5 has a max of 9 in column(s) 8 Row 6 has a max of 6 in column(s) 5, 6, 7, 8 Row 7 has a max of 9 in column(s) 7 Row 8 has a max of 8 in column(s) 0 Row 9 has a max of 9 in column(s) 0
Your output will vary because the dataset is built up with random numbers.
Dave
In reply to Re: how to loop through many arrays
by davido
in thread how to loop through many arrays
by david_lyon
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |