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

Hi,

I have a array (@array) which holds around 2500 integer variables. Now, I want to add First 10 $array values ($array[0]+$array1+...+$array9) as first set. Then next 10 values ($array10+$array11+...+$array19) and so on.

For example. $Path/$Sample_ID.Count.txt file looks like this

Sample1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 .....

Sample2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 .....

Sample3 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 .....

So, I want; $Path/$Sample_ID.NewCount.txt, like this

Sample1 10 40 30 40 .....

Sample2 10 20 30 40 .....

Sample3 20 40 30 40 .....

I tried to write some code. But cant get the result. In fact I am getting the output similar to the Input file.

Please have a look. Thanks.

open (IN, "$Path/$Sample_ID.Count.txt") or die; open my $SCR_chr1, '>>', "$Path/$Sample_ID.NewCount.txt" or die "Canno +t create file for output: $!"; # go through the file line by line while (my $line = <IN>) { # split the current line on tabs chomp ($line); chop($line) if ($line =~ m/\r$/); my @columns = split(/\t/, $line); print $SCR_chr1 "$columns[0]"; #Will print the Sample +_ID in the #first column of t +he raw in new text file. for ($columns[0] =~ m/chr1$/) #if column[0] has speci +fic Sample ID { #and uses the ~2500 tab- +separated values in this raw for( my $i = 1; $i <= 250; $i++ ) { for( my $j; $j <= 10; $j++ ) ## I am hoping to parse +first 10 columns (2-11) { ## But I dont know how to us +e the Next 10 columns (12-21) in next run of for loop. my $Column_Value += $columns[$j]; ## And add these va +lue [first 10 columns (2-11)] to new variable } print $SCR_chr1 "\t$Column_Value "; ## and Print as new + column in the file } print $SCR_chr1 "\n"; break; } }

Replies are listed 'Best First'.
Re: Nested for loop: Add arrays values in 1 set of 10
by Athanasius (Cardinal) on Aug 12, 2015 at 06:28 UTC

    Hello amitgsir, and welcome to the Monastery!

    For calculating the sum of a list of numbers, the core module List::Util provides the sum function. And for iterating over an array in fixed-size chunks, the module List::MoreUtils provides natatime:

    #! perl use strict; use warnings; use List::Util qw(sum); use List::MoreUtils qw(natatime); my @ints = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4); my $it = natatime 10, @ints; while (my @vals = $it->()) { my $sum = sum @vals; print $sum, "\n"; }

    Output:

    16:27 >perl 1338_SoPW.pl 10 40 30 40 16:27 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Nested for loop: Add arrays values in 1 set of 10
by Monk::Thomas (Friar) on Aug 12, 2015 at 08:19 UTC

    The second 'set' of your provided sample values contains 11 values. Is this a copy and paste error or intentional?

    btw. you can provide split with a third argument to limit the number of values you want. So instead of using natatime() you could write:

    while (my $line = <IN>) { ... my $remains = $line; while ($remains) { my (@set, $remains) = split /\t/, $remains, 11; # do something with 'sum(@set)' } }

    If there are less then 11 values left, then $remains will be set to undef and the inner loop terminates on the next iteration. The last set may contain less then 10 values - split does not complain, since the provided count value is just an upper limit.

Re: Nested for loop: Add arrays values in 1 set of 10
by amitgsir (Novice) on Aug 12, 2015 at 07:12 UTC
    Thank you very much Athanasius for your warm welcome and Kind reply. It really helped. Looks like I need to step-up to use the CPAN-Modules. Thanks again!! Amit
      The List::Utils module is core, meaning that it is delivered and installed with any distribution of Perl. The List::MoreUtils probably needs to be installed from the CPAN.

      And, yes, you should probably use them, but just in case you worry about how to do it in "pure Perl" (i.e. not using modules), which might be useful for learning purposes, this small session under the Perl debugger gives an idea on how you might do it:

      DB<1> @array = qw/1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 2 2 2 2 2 + 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3/; DB<2> while (@array) { $sum = 0; $sum += shift @array for 1..10; pri +nt "$sum\n";}; 10 40 20 30
      A real life program would need to do a bit more error checking than that, but you've got the basic idea. Note that at the end, the array is empty, so that if you need to keep the array you would have to first do a copy of it.