I'm trying to write terse Perl code to calculate the average of each column in a file. The file can have >= 1 columns.

use strict;
use warnings;
use List::Util qw/sum/;

my @aoc = ();
while (<DATA>) {
  my $c = 0;
  push @{ $aoc[$c++] }, $_ foreach (split);
print join (" ", map { sum(@$_)/@$_ } @aoc), $/;

#output: 2.66666666666667 26.6666666666667 266.666666666667

1 10 100
3 30 300
4 40 400

Can this code be any terser? I tried to remove while (<DATA>) by replacing split with map { $c = 0; split } <DATA> but this does not reset $c to 0 for each loop.

Any ideas on how to reduce this code further?


Following @mpapec suggestion, your code becomes (in pseudocode):

@columns = transpose(map (split " ", readlines("filename")))
print join (" ", map { sum(@$_)/@$_ } (columns), $/;

Where readlines reads a file into an array of lines.

To find the transpose function you will have to follow the link @mpapec gave you.

Your code is now down to just two lines and uses functional programming, that seems to be encouraged in Perl, so it looks better to me.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.