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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.