This is all very interesting to read. I've put some say statements in the new getsubset to figure out aspects of the parameter array and matrix manipulations. I'll put abridged output and (unabridged) source between readmore tags and pull out the bits I want to ask about after. All of the useful source in this has been listed upthread, so I'd probably skip to the code niblets...

... inside first anonymous block parameter array at top is ARRAY(0x5600d58ded50) R3 default is R3 data is4 parameter array at bottom is ARRAY(0x5600d58ded50) R3 data is 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 12 13 14 15 16 17 18 19 20 51 52 53 54 55 56 57 58 59 60 leaving getsubset 11 12 13 14 15 16 17 18 19 20 ok 19 11 12 13 14 15 16 17 18 19 20 11 12 13 14 15 66 17 18 19 20 exiting first anonymous block ---------- 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 12 13 14 15 66 17 18 19 20 51 52 53 54 55 56 57 58 59 60 ---------- parameter array at top is ARRAY(0x5600d58ded50) C2 default is C2 data is4 parameter array at bottom is ARRAY(0x5600d58ded50) C2 data is 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 12 13 14 15 66 17 18 19 20 51 52 53 54 55 56 57 58 59 60 leaving getsubset 2 b 12 52 ok 20 2 b 21 52 exit 2nd ---------- 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 21 13 14 15 66 17 18 19 20 51 52 53 54 55 56 57 58 59 60 ---------- parameter array at top is ARRAY(0x5600d58ded50) R4C2 default is R4C2 data is4 parameter array at bottom is ARRAY(0x5600d58ded50) R4C2 data is 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 21 13 14 15 66 17 18 19 20 51 52 53 54 55 56 57 58 59 60 leaving getsubset 52 ok 21 end 3rd ---------- 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 21 13 14 15 66 17 18 19 20 51 42 53 54 55 56 57 58 59 60 ---------- parameter array at top is ARRAY(0x5600d58ded50) R2C5:R4C8 default is R2C5:R4C8 data is4 parameter array at bottom is ARRAY(0x5600d58ded50) R2C5:R4C8 data is 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 21 13 14 15 66 17 18 19 20 51 42 53 54 55 56 57 58 59 60 leaving getsubset e f g h 15 66 17 18 55 56 57 58 ok 22 added 5 to a value ---------- 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 21 13 14 15 66 22 18 19 20 51 42 53 54 55 56 57 58 59 60 ---------- parameter array at top is ARRAY(0x5600d58ded50) C8:Cn default is C8:Cn data is4 parameter array at bottom is ARRAY(0x5600d58ded50) C8:Cn data is 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j 11 21 13 14 15 66 22 18 19 20 51 42 53 54 55 56 57 58 59 60 leaving getsubset 8 9 10 h i j 18 19 20 58 59 60 ok 23 substitutes X ---------- 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i X 11 21 13 14 15 66 22 18 19 20 51 42 53 54 55 56 57 58 59 60 ---------- parameter array at top is ARRAY(0x5600d58ded50) R4 default is R4 data is4 parameter array at bottom is ARRAY(0x5600d58ded50) R4 data is 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i X 11 21 13 14 15 66 22 18 19 20 51 42 53 54 55 56 57 58 59 60 leaving getsubset 51 42 53 54 55 56 57 58 59 60 ok 24 ---------- 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i X 11 21 13 14 15 66 22 18 19 20 51 42 53 54 55 56 57 58 59 60 ---------- ok 25 ## end abridged output begin source $ cat 2.da.pl #!/usr/bin/perl -w use 5.011; use Carp; use Data::Alias 'alias'; use Data::Dumper; sub print_aoa { use warnings; use 5.011; my $a = shift; my @array = @$a; for my $row (@array) { print join( " ", @{$row} ), "\n"; } return $a; } sub rangeparse { local $_ = shift; say "default is $_"; my @o; # [ row1,col1, row2,col2 ] (-1 = last row/col) if ( @o = /\AR([0-9]+|n)C([0-9]+|n):R([0-9]+|n)C([0-9]+|n)\z/ ) { } elsif (/\AR([0-9]+|n):R([0-9]+|n)\z/) { @o = ( $1, 1, $2, -1 ) } elsif (/\AC([0-9]+|n):C([0-9]+|n)\z/) { @o = ( 1, $1, -1, $2 ) } elsif (/\AR([0-9]+|n)C([0-9]+|n)\z/) { @o = ( $1, $2, $1, $2 ) } elsif (/\AR([0-9]+|n)\z/) { @o = ( $1, 1, $1, -1 ) } elsif (/\AC([0-9]+|n)\z/) { @o = ( 1, $1, -1, $1 ) } else { croak "failed to parse '$_'" } $_ eq 'n' and $_ <readmore>= -1 for @o; return \@o; } sub getsubset { my ( $data, $range ) = @_; say "parameter array at top is @_"; my $cols = @{ $$data[0] }; @$_ == $cols or croak "data not rectangular" for @$data; $range = rangeparse($range) unless ref $range eq 'ARRAY'; @$range == 4 or croak "bad size of range"; say "data is", 0 + @$data; my @max = ( 0 + @$data, $cols ) x 2; # say "max is @max"; max is 4 10 4 10 for my $i ( 0 .. 3 ) { $$range[$i] = $max[$i] if $$range[$i] < 0; croak "index $i out of range" if $$range[$i] < 1 || $$range[$i] > $max[$i]; } croak "bad rows $$range[0]-$$range[2]" if $$range[0] > $$range[2]; croak "bad cols $$range[1]-$$range[3]" if $$range[1] > $$range[3]; my @cis = $$range[1] - 1 .. $$range[3] - 1; say "parameter array at bottom is @_"; say "data is"; print_aoa($data); say "leaving getsubset"; return [ map { sub { \@_ } ->( @{ $$data[$_] }[@cis] ) } $$range[0] - 1 .. $$range[2] - 1 ]; } use Test::More tests => 25; is_deeply rangeparse("R1"), [ 1, 1, 1, -1 ]; is_deeply rangeparse("C1"), [ 1, 1, -1, 1 ]; is_deeply rangeparse("Rn"), [ -1, 1, -1, -1 ]; is_deeply rangeparse("Cn"), [ 1, -1, -1, -1 ]; is_deeply rangeparse("R4C5"), [ 4, 5, 4, 5 ]; is_deeply rangeparse("RnCn"), [ -1, -1, -1, -1 ]; is_deeply rangeparse("R2:R3"), [ 2, 1, 3, -1 ]; is_deeply rangeparse("C2:C3"), [ 1, 2, -1, 3 ]; is_deeply rangeparse("R4:Rn"), [ 4, 1, -1, -1 ]; is_deeply rangeparse("C5:Cn"), [ 1, 5, -1, -1 ]; is_deeply rangeparse("R2C3:R4C5"), [ 2, 3, 4, 5 ]; is_deeply rangeparse("R4C3:R4C3"), [ 4, 3, 4, 3 ]; is_deeply rangeparse("R5C1:R5C9"), [ 5, 1, 5, 9 ]; is_deeply rangeparse("R2C6:R11C6"), [ 2, 6, 11, 6 ]; is_deeply rangeparse("R3C1:RnC2"), [ 3, 1, -1, 2 ]; is_deeply rangeparse("R5C4:R5Cn"), [ 5, 4, 5, -1 ]; is_deeply rangeparse("RnC2:RnC5"), [ -1, 2, -1, 5 ]; is_deeply rangeparse("R3C2:RnCn"), [ 3, 2, -1, -1 ]; my $data = [ [ 1 .. 10 ], [ 'a' .. 'j' ], [ 11 .. 20 ], [ 51 .. 60 ] ] +; { say "inside first anonymous block"; my $subset = getsubset( $data, "R3" ); print_aoa $subset; is_deeply $subset, [ [ 11 .. 20 ] ]; print_aoa $subset; $subset->[0][5] = 66; print_aoa $subset; say "exiting first anonymous block"; } say "----------"; print_aoa $data; say "----------"; { my $subset = getsubset( $data, "C2" ); print_aoa $subset; is_deeply $subset, [ [2], ['b'], [12], [52] ]; $subset->[2][0] = 21; print_aoa $subset; say "exit 2nd"; } say "----------"; print_aoa $data; say "----------"; { my $subset = getsubset( $data, "R4C2" ); print_aoa $subset; is_deeply $subset, [ [52] ]; $subset->[0][0] = 42; say "end 3rd"; } say "----------"; print_aoa $data; say "----------"; { my $subset = getsubset( $data, "R2C5:R4C8" ); print_aoa $subset; is_deeply $subset, [ [ 'e' .. 'h' ], [ 15, 66, 17, 18 ], [ 55, 56, 5 +7, 58 ] ]; $subset->[1][2] += 5; say "added 5 to a value"; } say "----------"; print_aoa $data; say "----------"; { my $subset = getsubset( $data, "C8:Cn" ); print_aoa $subset; is_deeply $subset, [ [ 8 .. 10 ], [ 'h' .. 'j' ], [ 18 .. 20 ], [ 58 .. 60 ] ]; $subset->[1][2] = 'X'; say "substitutes X"; } say "----------"; print_aoa $data; say "----------"; { my $subset = getsubset( $data, "R4" ); print_aoa $subset; is_deeply $subset, [ [ 51, 42, 53, 54, 55, 56, 57, 58, 59, 60 ] ]; #$subset->[0][0] = 'M'; #say "substitutes M"; } say "----------"; print_aoa $data; say "----------"; is_deeply $data, [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [qw/a b c d e f g h i X/], [ 11, 21, 13, 14, 15, 66, 22, 18, 19, 20 ], [ 51, 42, 53, 54, 55, 56, 57, 58, 59, 60 ] ]; $

I have not seen this syntax before, and just to be sure, I thumbed through _Learning Perl_, not seeing it in chapter 4, Lists and Arrays. Asking google what "perl arrays x 2" means does not ask an effective question.

  my @max = ( 0 + @$data, $cols ) x 2;

I'm just looking for a reference to read up on that. The second thing I wanted to bring up was about the parameter array. Is it the case that @_ does not change over the life of the function? Does it have intrinsic aliasing?

Finally, after days of tinkering with it, I'm still baffled by the return from getsubset. We know what it's to be because we print it out when it gets returned. Lo and behold, it is a reference to an array. I can't see how the sausage gets made here:

return [ map { sub { \@_ } ->( @{ $$data[$_] }[@cis] ) } $$range[0] - 1 .. $$range[2] - 1 ];

You use the range operator once. LanX (upthread for the curious) used it twice:

return [ map { arr_alias @$_[ $cols->[0] .. $cols->[1] ] # x-slice } @$data[ $rows->[0] .. $rows->[1] ] # y-slice ];

Are they logically equivalent? Thanks for your comment and raising a topic I haven't looked at in perl very far. (Scientific computing in my day was fortran.) Wouldn't it be relatively easy to display these values using Tk::TableMatrix?


In reply to Re^3: Selecting Ranges of 2-Dimensional Data by Aldebaran
in thread Selecting Ranges of 2-Dimensional Data by haukex

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.