0

The following array is the result of a database query, and I would like to add a column in Perl:

<snip>
foreach my $array_ref ( @stash ) {
    print "@$array_ref\n";
}
<snip>

Output result:

bash-3.2$ ./test.pl
2014 2 1
2015 2 1
2016 2 1
2017 1 0.5
bash-3.2$

I manage to add a row at the bottom. For instance via the following code:

my @stashSum = ['Sum',  $sumNumDiv, $sumDiv];
push (@stash, @stashSum);

This results in the following:

bash-3.2$ ./test.pl
2014 2 1
2015 2 1
2016 2 1
2017 1 0.5
Sum  7 3.5
bash-3.2$

I am searching for the code to add the following as a column to the original array:

my $i=0;
foreach my $array_ref ( @stash ) {
    $totalDiv[$i] = $array_ref->[2] * 15;
    print "$totalDiv[$i] \n";   
}

The expected result is the following:

bash-3.2$ ./test.pl
2014 2 1 15
2015 2 1 15
2016 2 1 15
2017 1 0.5 7.5
bash-3.2$

Is there a way to 'push' a column onto an array in a similar manner as rows? If not, how are columns added to an array in Perl?

2
  • 1
    foreach my $array_ref ( @stash ) { push @$array_ref, "new_column" } Commented Jul 22, 2017 at 15:31
  • Thanks works splendidly!! Commented Jul 22, 2017 at 16:10

1 Answer 1

3

What you seem to have is an array of references to anonymous arrays, to which you are referring using matrix terminology where columns refer to elements of those anonymous arrays, and rows are the anonymous arrays themselves.

Adding a column therefore involves manipulating each of those arrays in terms of prepending, inserting, or appending another entry in the right spot. splice is helpful for that kind of thing.

#!/usr/bin/env perl

use strict;
use warnings;

use Test::More;

my $x = [ [1], [2] ]; # Two rows, single column

my @tests = (
    [ sub { push_column($x, 3) },    [     [1,3], [2,3]     ] ],
    [ sub { unshift_column($x, 4) }, [   [4,1,3], [4,2,3]   ] ],
    [ sub { add_column($x, 5, 1) },  [ [4,5,1,3], [4,5,2,3] ] ],
);

for my $case ( @tests ) {
    $case->[0]->();
    is_deeply $x, $case->[1];
}

sub add_column {
    my ($matrix, $v, $col) = @_;
    for my $r ( @$matrix ) {
        splice @$r, $col, 0, $v;
    }
    return;
}

sub push_column {
    add_column(@_, scalar @{ $x->[0] });
    return;
}

sub unshift_column {
    add_column(@_, 0);
    return;
}


done_testing;
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for this! I am still struggling with prepending a column to @stash. For instance, I generate a numbering column:
if (@stash) { for $i (1..$rowsDiv){ my $n=$i-1; $Div[$n]=$i; } }
With the following as expected result:
bash-3.2$ ./test.pl 1 2014 2 1 15 2 2015 2 1 15 3 2016 2 1 15 4 2017 1 0.5 7.5 bash-3.2$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.