# Problem with splice in a 2D ARRAY

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

Hello, I have a 2D array and want to interchange rows and columns.

I have done this test and it fails talking about flips and flops.
The perldoc -f splice is not of much help to swap 2 rows in a 2D
array (4 parameters as argument).

#!/usr/local/bin/perl -W

for \$x (0,1){
for \$y (0,1){
\$xy[\$x][\$y]= ++\$count;
}
}

splice @xy, 0, 1, \$xy[1][0..1];

for \$x (0,1){
for \$y (0,1){
print "\$xy[\$x][\$y] ";
}
print "\n";
}

__END__

Thanks in advance for any help

## Re: Problem with splice in a 2D ARRAY

There is no such thing as 'a 2D array' in Perl. What you create here
is a two-element array containing two references to two anonymous
two-element arrays each containing two numbers each. Swapping the two
'rows' aka 'anonymous two-element arrays' can be done with

@xy[0,1] = @xy[1,0]

or

splice(@xy, 0, 2, @xy[1,0])

## Re: Problem with splice in a 2D ARRAY

There is no such thing as 'a 2D array' in Perl. What you create here
is a two-element array containing two references to two anonymous
two-element arrays each containing two numbers. Swapping the two
'rows' aka 'anonymous two-element arrays' can be done with

@xy[0,1] = @xy[1,0]

or

splice(@xy, 0, 2, @xy[1,0])

## Re: Problem with splice in a 2D ARRAY

Both works fine, but as I infer there is no simple way to do that
by columns.

thank you very much

--
posted by mobile device

----Android NewsGroup Reader----
http://www.piaohong.tk/newsgroup

## Re: Problem with splice in a 2D ARRAY

Well, did you try the obvious way?

my @old = ...;
my @new;

for my \$r (0..\$#old) {
my \$row = \$old[\$r];
for my \$c (0..\$#\$row) {
\$new[\$c][\$r] = \$\$row[\$c];
}
}

I'm not sure it's possible to do that any more elegantly, given that you
can't take a slice vertically through a 2d array.

What did you expect this to do? The 0..1 is in scalar context, so this
is the flip-flop operator, which I don't think is what you meant.

Ben

## Re: Problem with splice in a 2D ARRAY

for my \$r (0..\$#old) {
my \$row = \$old[\$r];
for my \$c (0..\$#\$row) {
\$new[\$c][\$r] = \$\$row[\$c];
}
}

I'm not sure it's possible to do that any more elegantly, given that you
can't take a slice vertically through a 2d array.

--------------------

Well, that does a tansposition, and after that is posible to do the
column swap:

my @xy = @new;

for \$y (0,1){
(\$xy[0][\$y],\$xy[1][\$y]) = (\$xy[1][\$y],\$xy[0][\$y]);
}

and redo the transposition. Or directly,

for \$x (0,1){
(\$xy[\$x][0],\$xy[\$x][1]) = (\$xy[\$x][1],\$xy[\$x][0]);
}

Anyway, it could be done without splice. Thank you, I'll try to resume
it to work with randomized small square matrix.

Best regards,

## Re: Problem with splice in a 2D ARRAY

Please quote properly, and attribute your quotations.

Yes. You asked how to interchange rows and columns; that's what a
transposition does.

So you're actually trying to exchange two columns. Yes, that is the way
to do it. For the more general case of reversing the columns of a NxM
matrix, you want

for my \$r (@matrix) {
splice @\$r, 0, \$#r, reverse @\$r;
}

You should look on CPAN: a lot of this sort of basic stuff has already
been implemented.

Ben

## Re: Problem with splice in a 2D ARRAY

So you're actually trying to exchange two columns. Yes, that is the way
to do it. For the more general case of reversing the columns of a NxM
matrix, you want

for my \$r (@matrix) {
splice @\$r, 0, \$#r, reverse @\$r;
}

You should look on CPAN: a lot of this sort of basic stuff has already
been implemented.

Ben
---------------------------

very useful, thanks

I see things like Array::Utils, but it's about operations onm two matrix.
Math::MatrixReal is excelent but it's for computations purpose. I don't
know how to search more.

Thanks again

## Re: Problem with splice in a 2D ARRAY

On 6/17/2013 1:36 PM, gamo@telecable.es wrote:

use List::MoreUtils qw/each_arrayref/;

my @old = (...);
my @new;

my \$iter = each_arrayref( @old );
while (my @row = \$iter->()) { push @new, [reverse @row] };

--
Charles DeRykus

## Re: Problem with splice in a 2D ARRAY

On 6/17/2013 3:05 PM, Charles DeRykus wrote:

Sorry, I see the mis-attribution now... still not sure what was wanted.
But my above suggestion both transposes and swaps.

If just transposing with no swap:

my \$iter = each_arrayref( @old );
while (my @row = \$iter->()) { push @new, \@row };

--
Charles DeRykus

## Re: Problem with splice in a 2D ARRAY

Quoth gamo@telecable.es:

Did you read the bit before where I asked you to quote properly? That
means: insert a '>' at the start of each line you are quoting, and
include a header saying whose message you are quoting from.

Well, a quick look finds Math::Matrix and Array::DeepUtils, as well as
things like PDL which are probably a more suitable representation if
you're using matrices for calculations.

Ben

## Re: Problem with splice in a 2D ARRAY

sub transpose
{
my \$in = \$_[0];
my (@out, \$col);

for \$col (0 .. \$#) {
push(@out, [map { \$_->[\$col] } @\$in[0 .. \$#\$in]])
}

return \@out;
}

my @a = ([1,2,3,4], [4,5,6,7], [7,8,9,10]);
my \$at = transpose(\@a);

for (@\$at) {
print("\$_ ") for @\$_;
print("\n");
}

## Re: Problem with splice in a 2D ARRAY

[...]

This is, of course, equivalent to

push(@out, [map { \$_->[\$col] } @\$in])

## Re: Problem with splice in a 2D ARRAY

Yes, that's the same algorithm, just with map instead of for, though it
probably is worth pointing out that

map \$_->[\$col], @2d;

is the way to take a vertical slice.

Ben

## Re: Problem with splice in a 2D ARRAY

This means it is an equivalent algorithm and specifically,

I wrote it because it came to me that it was actually possible to get
'a vertical slice' out of 'a 2d array' with an expression instead of a
1-by-1 copying loop. It is also possible to get rid of the outer loop
(working with 'arrays' / 'lists' this time for a change):

sub transpose
{
my \$col;

return map {
\$col = \$_;
[map { \$_->[\$col] } @_]
} 0 .. \$#;
}