Split multidimensional array into 4 multidimensional arrays

Ask a Question related to PERL Beginners, Design and Development.

  1. #1

    Default Split multidimensional array into 4 multidimensional arrays

    Hello everyone,

    I have a multidimensional array that I need to split into 4
    multidimensional arrays. I've tried the examples from the Programming
    Perl 3rd ed. Chapter 9 for splicing Arrays of Arrays and am not having
    any luck.

    Here's an example of how my data looks:

    [1 2 3 4 5 6 7 8 9 10 11 12]
    [A B C D E F G H I J K L]

    Here's how I need it to look:

    [1 2 3 4] [5 6 7 8]
    [A B C D] [E F G H]

    [9 10] [11 12]
    [I J] [K L]

    The code I used

    #!/usr/bin/perl

    use warnings;
    use strict;
    use Data::Dumper;

    my @AoA = ();
    push @AoA, qw[1 2 3 4 5 6 7 8 9 10 11 12];
    push @AoA, qw[A B C D E F G H I J K L];

    print Dumper(\@AoA);

    my @newAoA = ();
    for (my $startx = my $x = 4; $x <= 8; $x++) {
    for (my $starty = my $y = 7; $y <= 12; $y++) {
    $newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
    }
    }

    print @newAoA;


    The error I got is:

    Can't use string ("5") as an ARRAY ref while "strict refs" in use at
    ../splice.pl line 16.


    Any ideas?

    Thanks in advance for any help!

    --
    Kevin Old <kold@kold.homelinux.com>

    Kevin Old Guest

  2. Similar Questions and Discussions

    1. Multidimensional arrays
      Hi Can anybody help me grasp multidimensional arrays please? Basically, I am retrieving all records from one table (two fields), and want to...
    2. sorting multidimensional arrays
      One last question about multi-dimensional arrays - I'm aware of the function array_multisort, but that keeps the relationship with the key - what do...
    3. Build multidimensional array from arrays
      Hello everyone, I have: @one = qw(A B C D); @two = qw(E F G H); I want to build a multidimensional array from the above arrays. I want to...
    4. Displaying Multidimensional Arrays
      I am trying to create a function that will take a multidimensional array and turn it into a form based off the information in the array. I have run...
    5. [PHP] Multidimensional arrays
      <snip> select id, name from customer redim custarray(recordcount,2) i = 0 while not eof custarray(i,0) = id; custarray(i,1) = name; i = i+1;...
  3. #2

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Wednesday, October 15, 2003, at 04:23 PM, Kevin Old wrote:
    > Hello everyone,
    >
    > I have a multidimensional array that I need to split into 4
    > multidimensional arrays. I've tried the examples from the Programming
    > Perl 3rd ed. Chapter 9 for splicing Arrays of Arrays and am not having
    > any luck.
    >
    > Here's an example of how my data looks:
    >
    > [1 2 3 4 5 6 7 8 9 10 11 12]
    > [A B C D E F G H I J K L]
    >
    > Here's how I need it to look:
    >
    > [1 2 3 4] [5 6 7 8]
    > [A B C D] [E F G H]
    >
    > [9 10] [11 12]
    > [I J] [K L]
    Hmm, I'm a little lost at this point.
    > The code I used
    >
    > #!/usr/bin/perl
    >
    > use warnings;
    > use strict;
    > use Data::Dumper;
    >
    > my @AoA = ();
    > push @AoA, qw[1 2 3 4 5 6 7 8 9 10 11 12];
    > push @AoA, qw[A B C D E F G H I J K L];
    This isn't an array of arrays at this point. Just want to make sure
    you know that. It's one long array with 1 - 12 at the front and A - L
    at the back.

    If you meant for this to be a multidimensional array, try:

    my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );
    > print Dumper(\@AoA);
    This would show that, if it was compiling.
    > my @newAoA = ();
    > for (my $startx = my $x = 4; $x <= 8; $x++) {
    > for (my $starty = my $y = 7; $y <= 12; $y++) {
    > $newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
    > }
    > }
    Obviously this code doesn't work. It's a referencing issue. I would
    try to correct it, but I don't understand the goal. Can you try taking
    another stab at explaining how the array should look in the end?

    James
    > print @newAoA;
    >
    >
    > The error I got is:
    >
    > Can't use string ("5") as an ARRAY ref while "strict refs" in use at
    > ./splice.pl line 16.
    >
    >
    > Any ideas?
    >
    > Thanks in advance for any help!
    >
    > --
    > Kevin Old <kold@kold.homelinux.com>
    >
    >
    > --
    > To unsubscribe, e-mail: [email]beginners-unsubscribe@perl.org[/email]
    > For additional commands, e-mail: [email]beginners-help@perl.org[/email]
    >
    James Edward Gray II Guest

  4. #3

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Wed, 2003-10-15 at 17:43, James Edward Gray II wrote:
    > On Wednesday, October 15, 2003, at 04:23 PM, Kevin Old wrote:
    >
    > > Hello everyone,
    > >
    > > I have a multidimensional array that I need to split into 4
    > > multidimensional arrays. I've tried the examples from the Programming
    > > Perl 3rd ed. Chapter 9 for splicing Arrays of Arrays and am not having
    > > any luck.
    > >
    > > Here's an example of how my data looks:
    > >
    > > [1 2 3 4 5 6 7 8 9 10 11 12]
    > > [A B C D E F G H I J K L]
    > >
    > > Here's how I need it to look:
    > >
    > > [1 2 3 4] [5 6 7 8]
    > > [A B C D] [E F G H]
    > >
    > > [9 10] [11 12]
    > > [I J] [K L]
    >
    > Hmm, I'm a little lost at this point.
    Yes, you're right. This is how I meant to define my array:

    my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );

    Ok, what I need is for the AoA to be reformatted like this into another
    AoA.


    1st 4 columns(1-4,A-D), "empty column", Next 4 columns(5-8,E-H)
    "empty row in AoA"
    Next 2 columns(9-10,I-J), "empty column", Last 2 columns(11-12,K-L)

    Does this explain it?

    Thanks for any help you can offer.
    >
    > > The code I used
    > >
    > > #!/usr/bin/perl
    > >
    > > use warnings;
    > > use strict;
    > > use Data::Dumper;
    > >
    > > my @AoA = ();
    > > push @AoA, qw[1 2 3 4 5 6 7 8 9 10 11 12];
    > > push @AoA, qw[A B C D E F G H I J K L];
    >
    > This isn't an array of arrays at this point. Just want to make sure
    > you know that. It's one long array with 1 - 12 at the front and A - L
    > at the back.
    >
    > If you meant for this to be a multidimensional array, try:
    >
    > my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );
    >
    > > print Dumper(\@AoA);
    >
    > This would show that, if it was compiling.
    >
    > > my @newAoA = ();
    > > for (my $startx = my $x = 4; $x <= 8; $x++) {
    > > for (my $starty = my $y = 7; $y <= 12; $y++) {
    > > $newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
    > > }
    > > }
    >
    > Obviously this code doesn't work. It's a referencing issue. I would
    > try to correct it, but I don't understand the goal. Can you try taking
    > another stab at explaining how the array should look in the end?
    BTW, this code is straight from Programming Perl 3rd ed. Chapter 9.

    Thanks for your help!

    Kevin

    --
    Kevin Old <kold@kold.homelinux.com>

    Kevin Old Guest

  5. #4

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Wednesday, October 15, 2003, at 08:22 PM, Kevin Old wrote:
    > Yes, you're right. This is how I meant to define my array:
    >
    > my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );
    >
    > Ok, what I need is for the AoA to be reformatted like this into another
    > AoA.
    >
    >
    > 1st 4 columns(1-4,A-D), "empty column", Next 4 columns(5-8,E-H)
    > "empty row in AoA"
    > Next 2 columns(9-10,I-J), "empty column", Last 2 columns(11-12,K-L)
    >
    > Does this explain it?
    I'm probably just slow, but not really no. Do you mean this?

    my @super_array = ( [ [ 1..4 ], undef, [ 5..8 ] ],
    [ [ 'A'..'D' ], undef, [ 'E'..'H' ] ],
    undef,
    [ [ 9, 10 ], undef, [ 11, 12 ] ],
    [ [ 'I', 'J' ], undef, [ 'K', 'L' ] ] );

    Just FYI, that's by far the scariest array I've ever tried to code up
    and I seriously doubt its usefulness.

    Now, if you meant a boring two-dimensional table, that's MUCH easier
    and more sane.

    my @array_2d = ( [ 1.. 4, undef, 5..8 ],
    [ 'A'..'D', undef, 'E'..'H' ],
    [ ],
    [ 9, 10, undef, 11, 12 ],
    [ 'I', 'J', undef, 'K', 'L' ] );

    If it's neither of those, try me again. I'm dumb, but I won't give up.
    ;)
    >>> my @newAoA = ();
    >>> for (my $startx = my $x = 4; $x <= 8; $x++) {
    >>> for (my $starty = my $y = 7; $y <= 12; $y++) {
    >>> $newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
    >>> }
    >>> }
    >>
    >> Obviously this code doesn't work. It's a referencing issue. I would
    >> try to correct it, but I don't understand the goal. Can you try taking
    >> another stab at explaining how the array should look in the end?
    >
    > BTW, this code is straight from Programming Perl 3rd ed. Chapter 9.
    Way to hit a sore spot man! I just packed my copy of Programming Perl
    to move and I'm very emotional over it!!! :D

    The code is okay. What was happening was that your @AoA was really
    just a long array of letters and numbers and didn't contain any
    internal references. Thus when the above code tried to dereference a 5
    as an array, it would choke and die.

    Hopefully something in my endless babble is helping you a little. I am
    trying! :) Are you just playing with some code, or do you have a goal
    I'm completely missing?

    James

    James Edward Gray II Guest

  6. #5

    Default Re: Split multidimensional array into 4 multidimensional arrays

    Kevin Old wrote:
    >
    > On Wed, 2003-10-15 at 17:43, James Edward Gray II wrote:
    > >
    > > On Wednesday, October 15, 2003, at 04:23 PM, Kevin Old wrote:
    > >
    > > > Hello everyone,
    > > >
    > > > I have a multidimensional array that I need to split into 4
    > > > multidimensional arrays. I've tried the examples from the Programming
    > > > Perl 3rd ed. Chapter 9 for splicing Arrays of Arrays and am not having
    > > > any luck.
    > > >
    > > > Here's an example of how my data looks:
    > > >
    > > > [1 2 3 4 5 6 7 8 9 10 11 12]
    > > > [A B C D E F G H I J K L]
    > > >
    > > > Here's how I need it to look:
    > > >
    > > > [1 2 3 4] [5 6 7 8]
    > > > [A B C D] [E F G H]
    > > >
    > > > [9 10] [11 12]
    > > > [I J] [K L]
    > >
    > > Hmm, I'm a little lost at this point.
    >
    > Yes, you're right. This is how I meant to define my array:
    >
    > my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );
    >
    > Ok, what I need is for the AoA to be reformatted like this into another
    > AoA.
    >
    >
    > 1st 4 columns(1-4,A-D), "empty column", Next 4 columns(5-8,E-H)
    > "empty row in AoA"
    > Next 2 columns(9-10,I-J), "empty column", Last 2 columns(11-12,K-L)
    >
    > Does this explain it?
    >
    > Thanks for any help you can offer.
    >
    > >
    > > > The code I used
    > > >
    > > > #!/usr/bin/perl
    > > >
    > > > use warnings;
    > > > use strict;
    > > > use Data::Dumper;
    > > >
    > > > my @AoA = ();
    > > > push @AoA, qw[1 2 3 4 5 6 7 8 9 10 11 12];
    > > > push @AoA, qw[A B C D E F G H I J K L];
    > >
    > > This isn't an array of arrays at this point. Just want to make sure
    > > you know that. It's one long array with 1 - 12 at the front and A - L
    > > at the back.
    > >
    > > If you meant for this to be a multidimensional array, try:
    > >
    > > my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );
    > >
    > > > print Dumper(\@AoA);
    > >
    > > This would show that, if it was compiling.
    > >
    > > > my @newAoA = ();
    > > > for (my $startx = my $x = 4; $x <= 8; $x++) {
    > > > for (my $starty = my $y = 7; $y <= 12; $y++) {
    > > > $newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
    > > > }
    > > > }
    > >
    > > Obviously this code doesn't work. It's a referencing issue. I would
    > > try to correct it, but I don't understand the goal. Can you try taking
    > > another stab at explaining how the array should look in the end?
    >
    > BTW, this code is straight from Programming Perl 3rd ed. Chapter 9.
    Hi Kevin.

    The program below does what I think you mean. But you end up with
    a three-dimensional array instead of the two-dimensional one you
    started with. Is that right?

    HTH,

    Rob



    use strict;
    use warnings;

    use Data::Dumper;

    my @AoA = ( [ 1 .. 12 ], [ 'A'..'L' ] );

    foreach (4, 4, undef, 2, 2) {

    if ( defined ) {
    push @AoA, [
    [ splice @{$AoA[0]}, 0, $_ ],
    undef,
    [ splice @{$AoA[1]}, 0, $_ ],
    ];
    }
    else {
    push @AoA, undef;
    }
    }

    splice @AoA, 0, 2; # Remove the original two rows

    print Data::Dumper->Dump( [\@AoA], ['*AoA'] );

    ** OUTPUT ** (reformatted)

    @AoA = (
    [
    [ 1, 2, 3, 4 ],
    undef,
    [ 'A', 'B', 'C', 'D' ]
    ],
    [
    [ 5, 6, 7, 8 ],
    undef,
    [ 'E', 'F', 'G', 'H' ]
    ],
    undef,
    [
    [ 9, 10 ],
    undef,
    [ 'I', 'J' ]
    ],
    [
    [ 11, 12 ],
    undef,
    [ 'K', 'L' ]
    ]
    );


    Rob Dixon Guest

  7. #6

    Default Re: Split multidimensional array into 4 multidimensional arrays

    James,

    On Wed, 2003-10-15 at 22:42, James Edward Gray II wrote:
    > Now, if you meant a boring two-dimensional table, that's MUCH easier
    > and more sane.
    >
    > my @array_2d = ( [ 1.. 4, undef, 5..8 ],
    > [ 'A'..'D', undef, 'E'..'H' ],
    > [ ],
    > [ 9, 10, undef, 11, 12 ],
    > [ 'I', 'J', undef, 'K', 'L' ] );
    >
    > If it's neither of those, try me again. I'm dumb, but I won't give up.
    > ;)
    Yes, this is what I'm trying to get for a result. I'm dumb too, that's
    why I'm formatting data this way.

    What needed to happen was that the data be broken down and displayed
    into quadrants out of the two-dimensional array. I say needed because
    the data feed I get has been reformatted so I don't have to worry about
    that anymore.

    I would however be interested in knowing how to get my previous array
    into the @array_2d above.
    > > BTW, this code is straight from Programming Perl 3rd ed. Chapter 9.
    >
    > Way to hit a sore spot man! I just packed my copy of Programming Perl
    > to move and I'm very emotional over it!!! :D
    I treasure it too. I wasn't doubting it's code, it was MY code I was
    questioning.

    Thanks for all you're help!
    Kevin
    --
    Kevin Old <kold@kold.homelinux.com>

    Kevin Old Guest

  8. #7

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Thursday, October 16, 2003, at 09:16 AM, Kevin Old wrote:
    > James,
    >
    > On Wed, 2003-10-15 at 22:42, James Edward Gray II wrote:
    >
    >> Now, if you meant a boring two-dimensional table, that's MUCH easier
    >> and more sane.
    >>
    >> my @array_2d = ( [ 1.. 4, undef, 5..8 ],
    >> [ 'A'..'D', undef, 'E'..'H' ],
    >> [ ],
    >> [ 9, 10, undef, 11, 12 ],
    >> [ 'I', 'J', undef, 'K', 'L' ] );
    >>
    >> If it's neither of those, try me again. I'm dumb, but I won't give
    >> up.
    >> ;)
    >
    > Yes, this is what I'm trying to get for a result. I'm dumb too, that's
    > why I'm formatting data this way.
    >
    > What needed to happen was that the data be broken down and displayed
    > into quadrants out of the two-dimensional array. I say needed because
    > the data feed I get has been reformatted so I don't have to worry about
    > that anymore.
    >
    > I would however be interested in knowing how to get my previous array
    > into the @array_2d above.
    That's a tricky question for me to answer. I can think of a lot of
    ways to change it, but I'm not sure I understand the pattern you were
    using. If I had divided 12 items equally into quadrants it would have
    been three per quad. I might have done that like:

    #!/usr/bin/perl

    use strict;
    use warnings;

    use Data::Dumper;

    my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );

    print Dumper(\@AoA);

    # figure out where to break them up
    my $quad_count = @{$AoA[0]} / 4;
    $quad_count++ if $quad_count =~ s/\.\d+$//; # round up

    my @array_2d = ( [ ], [ ], [ ], [ ], [ ] );
    # walk the old rows index by index moving them to the new array
    # in the right spot
    for my $old_row ( 0, 1 ) {
    for my $index ( 0 .. $#{$AoA[0]} ) {
    my $new_row = $index < 2 * $quad_count ? $old_row : $old_row + 3;
    if ( $index < 2 * $quad_count ) {
    $array_2d[ $new_row ][ $index ] = $AoA[ $old_row ][ $index ];
    }
    else {
    $array_2d[ $new_row ][ $index - 2 * $quad_count ] =
    $AoA[ $old_row ][ $index ];
    }
    }
    }
    # add undefs to break up the quads
    splice @{ $array_2d[ $_ ] }, $quad_count, 0, undef foreach 0, 1, 3, 4;

    print Dumper(\@array_2d);

    __END__

    However, not understanding your pattern, I probably would have written
    the much uglier and nearly useless:

    #!/usr/bin/perl

    use strict;
    use warnings;

    use Data::Dumper;

    my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );

    print Dumper(\@AoA);

    my @array_2d = ( [ ], [ ], [ ], [ ], [ ] );
    push @{ $array_2d[0] }, @{ $AoA[0] }[ 0..3 ], undef, @{ $AoA[0] }[ 4..7
    ];
    push @{ $array_2d[1] }, @{ $AoA[1] }[ 0..3 ], undef, @{ $AoA[1] }[ 4..7
    ];
    push @{ $array_2d[3] }, @{ $AoA[0] }[ 8, 9 ], undef, @{ $AoA[0] }[ 10,
    11 ];
    push @{ $array_2d[4] }, @{ $AoA[1] }[ 8, 9 ], undef, @{ $AoA[1] }[ 10,
    11 ];

    print Dumper(\@array_2d);

    __END__

    Given that, I figured it was better just to show it in assignment form.

    Maybe it you explain how you were dividing them up, I could do a little
    better. Sorry if I'm still not helping much.

    James

    James Edward Gray II Guest

  9. #8

    Default Re: Split multidimensional array into 4 multidimensional arrays

    In article <1066252996.2614.47.camel@localhost.localdomain> , Kevin Old
    wrote:
    > Hello everyone,
    >
    > I have a multidimensional array that I need to split into 4
    > multidimensional arrays. I've tried the examples from the Programming
    > Perl 3rd ed. Chapter 9 for splicing Arrays of Arrays and am not having
    > any luck.
    >
    > Here's an example of how my data looks:
    >
    > [1 2 3 4 5 6 7 8 9 10 11 12]
    > [A B C D E F G H I J K L]
    >
    > Here's how I need it to look:
    >
    > [1 2 3 4] [5 6 7 8]
    > [A B C D] [E F G H]
    >
    > [9 10] [11 12]
    > [I J] [K L]
    Here's my version (I did need to peek at the Cookbook). I think this is what
    you asked for...

    my @AoA = (
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
    ['A'..'L'],
    );

    my (@AoA1, @AoA2, @AoA3, @AoA4);

    for (0..$#AoA) {
    # slice of AoA -- note position of {}s for AoA slice !!!!
    push @AoA1, [ @{$AoA[$_]}[0..3] ];
    push @AoA2, [ @{$AoA[$_]}[4..7] ];
    push @AoA3, [ @{$AoA[$_]}[8..9] ];
    push @AoA4, [ @{$AoA[$_]}[10..11] ];
    }

    # print Dumper(\@AoA1);

    print "Array 1:\n";
    foreach (@AoA1) {
    print "@{$_}\n";
    }

    print "\n\n";

    print "Array 2:\n";
    foreach (@AoA2) {
    print "@{$_}\n";
    }

    print "\n\n";

    print "Array 3:\n";
    foreach (@AoA3) {
    print "@{$_}\n";
    }

    print "\n\n";


    print "Array 4:\n";
    foreach (@AoA4) {
    print "@{$_}\n";
    }

    __END__

    Output:

    Array 1:
    1 2 3 4
    A B C D


    Array 2:
    5 6 7 8
    E F G H


    Array 3:
    9 10
    I J


    Array 4:
    11 12
    K L


    Am I close?



    -K
    --
    Kevin Pfeiffer
    International University Bremen

    Kevin Pfeiffer Guest

  10. #9

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Thu, 2003-10-16 at 11:52, James Edward Gray II wrote:
    > On Thursday, October 16, 2003, at 09:16 AM, Kevin Old wrote:
    >
    > > James,
    > >
    > > On Wed, 2003-10-15 at 22:42, James Edward Gray II wrote:
    > >
    > >> Now, if you meant a boring two-dimensional table, that's MUCH easier
    > >> and more sane.
    > >>
    > >> my @array_2d = ( [ 1.. 4, undef, 5..8 ],
    > >> [ 'A'..'D', undef, 'E'..'H' ],
    > >> [ ],
    > >> [ 9, 10, undef, 11, 12 ],
    > >> [ 'I', 'J', undef, 'K', 'L' ] );
    > >>
    > >> If it's neither of those, try me again. I'm dumb, but I won't give
    > >> up.
    > >> ;)
    > >
    > > Yes, this is what I'm trying to get for a result. I'm dumb too, that's
    > > why I'm formatting data this way.
    > >
    > > What needed to happen was that the data be broken down and displayed
    > > into quadrants out of the two-dimensional array. I say needed because
    > > the data feed I get has been reformatted so I don't have to worry about
    > > that anymore.
    > >
    > > I would however be interested in knowing how to get my previous array
    > > into the @array_2d above.
    >
    > That's a tricky question for me to answer. I can think of a lot of
    > ways to change it, but I'm not sure I understand the pattern you were
    > using. If I had divided 12 items equally into quadrants it would have
    > been three per quad. I might have done that like:
    >
    > #!/usr/bin/perl
    >
    > use strict;
    > use warnings;
    >
    > use Data::Dumper;
    >
    > my @AoA = ( [ 1..12 ], [ 'A'..'L' ] );
    >
    > print Dumper(\@AoA);
    >
    > # figure out where to break them up
    > my $quad_count = @{$AoA[0]} / 4;
    > $quad_count++ if $quad_count =~ s/\.\d+$//; # round up
    >
    > my @array_2d = ( [ ], [ ], [ ], [ ], [ ] );
    > # walk the old rows index by index moving them to the new array
    > # in the right spot
    > for my $old_row ( 0, 1 ) {
    > for my $index ( 0 .. $#{$AoA[0]} ) {
    > my $new_row = $index < 2 * $quad_count ? $old_row : $old_row + 3;
    > if ( $index < 2 * $quad_count ) {
    > $array_2d[ $new_row ][ $index ] = $AoA[ $old_row ][ $index ];
    > }
    > else {
    > $array_2d[ $new_row ][ $index - 2 * $quad_count ] =
    > $AoA[ $old_row ][ $index ];
    > }
    > }
    > }
    > # add undefs to break up the quads
    > splice @{ $array_2d[ $_ ] }, $quad_count, 0, undef foreach 0, 1, 3, 4;
    >
    > print Dumper(\@array_2d);
    >
    > __END__
    >
    James, is it possible to ask for a little more help with this?

    Here's the actual data I'm parsing (it's padded with spaces, but dont'
    worry about them) and delimited by semicolon's.

    DATE;WM REPL SHIPPED;STD REPL SHIPPED;PROMO SHIPPED;ROLLOUT
    SHIPPED;OTHER SHIPPED;M/I SHIPPED;TOTAL SHIPPED;WM REPL OPEN;STD REPL
    OPEN;PROMO OPEN;ROLLOUT OPEN;OTHER OPEN;M/I OPEN;TOTAL OPEN;LATE
    ORDERS;DUMMY ORDERS;DELETED ORDERS;HELD ORDERS
    ; ; ; ; ;
    ; ; ; ; ;
    ; ; ; ; ;
    ; ; ;
    20031002; 5764; 114978; 2288; ;
    39; ; 123069; ; ;
    ; ; ; ; ;
    ; ; ;
    20031003; 55523; 54923; 1105840; ;
    157597; 3220; 1377103; ; ;
    ; ; ; ; ;
    ; ; ;
    20031006; 64457; 152142; 771045; ;
    46; 1319; 989009; ; ;
    ; ; ; ; ;
    ; ; ;
    20031007; 17841; 49993; 190107; ;
    28778; 6971; 293690; ; ;
    ; ; ; ; ;
    ; ; ;
    20031008; 12347; 103861; 1323307; ;
    ; 9899; 1449414; ; ;
    ; ; ; ; ;
    ; ; ;
    20031009; 95842; 165819; 977485; ;
    3882; 9865; 1252893; ; ;
    ; ; ; ; ;
    ; ; ;
    20031010; 14384; 131304; 756744; ;
    18476; 2152; 923060; ; ;
    ; ; ; ; ;
    ; ; ;
    20031011; 109672; 132782; 89539; ;
    11900; 3834; 347727; ; ;
    ; ; ; ; ;
    ; ; ;
    20031012; 53112; 118962; 86163; ;
    ; ; 258237; ; ;
    ; ; ; ; ;
    ; ; ;
    20031013; 55604; 50646; ; ;
    ; ; 106250; ; ;
    ; ; ; ; ;
    ; ; ;
    20031014; 88531; 102857; 529651; ;
    ; 5782; 726821; 582234; 863117;
    9196512; ; 87790; 64738; 10794391;
    3740624; 50400; ;


    There are 19 columns and what I need is:

    The first 8 column in quadrant 1
    The next 7 columns in quadrant 2
    The Date column (from Q1, 1st column) again, plus the next 7 columns all
    in quadrant 3
    The last 4 columns in quadrant 4

    Now, the example above splits the 2D array by 4, placing 4 columns in
    each quadrant, but I can't figure out the math logic to alter it for my
    needs above.

    Any additional help you can offer would be absolutely awesome and would
    almost require me to send a keg ;).

    Thanks,
    --
    Kevin Old <kold@kold.homelinux.com>

    Kevin Old Guest

  11. #10

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Thursday, October 16, 2003, at 03:25 PM, Kevin Old wrote:
    > James, is it possible to ask for a little more help with this?
    Nope, you've used up all your free answer tokens. <laughs> Oh,
    alright, just this once...
    > Here's the actual data I'm parsing (it's padded with spaces, but dont'
    > worry about them) and delimited by semicolon's.
    Ah, the Real-Question-Switcheroo! ;)
    > DATE;WM REPL SHIPPED;STD REPL SHIPPED;PROMO SHIPPED;ROLLOUT
    > SHIPPED;OTHER SHIPPED;M/I SHIPPED;TOTAL SHIPPED;WM REPL OPEN;STD REPL
    > OPEN;PROMO OPEN;ROLLOUT OPEN;OTHER OPEN;M/I OPEN;TOTAL OPEN;LATE
    > ORDERS;DUMMY ORDERS;DELETED ORDERS;HELD ORDERS
    > ; ; ; ; ;
    > ; ; ; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031002; 5764; 114978; 2288; ;
    > 39; ; 123069; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031003; 55523; 54923; 1105840; ;
    > 157597; 3220; 1377103; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031006; 64457; 152142; 771045; ;
    > 46; 1319; 989009; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031007; 17841; 49993; 190107; ;
    > 28778; 6971; 293690; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031008; 12347; 103861; 1323307; ;
    > ; 9899; 1449414; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031009; 95842; 165819; 977485; ;
    > 3882; 9865; 1252893; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031010; 14384; 131304; 756744; ;
    > 18476; 2152; 923060; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031011; 109672; 132782; 89539; ;
    > 11900; 3834; 347727; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031012; 53112; 118962; 86163; ;
    > ; ; 258237; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031013; 55604; 50646; ; ;
    > ; ; 106250; ; ;
    > ; ; ; ; ;
    > ; ; ;
    > 20031014; 88531; 102857; 529651; ;
    > ; 5782; 726821; 582234; 863117;
    > 9196512; ; 87790; 64738; 10794391;
    > 3740624; 50400; ;
    >
    >
    > There are 19 columns and what I need is:
    >
    > The first 8 column in quadrant 1
    > The next 7 columns in quadrant 2
    > The Date column (from Q1, 1st column) again, plus the next 7 columns
    > all
    > in quadrant 3
    > The last 4 columns in quadrant 4
    Okay, are these quadrants on going lists I should keep adding rows too?
    I'm going to assume yes, for now.
    > Now, the example above splits the 2D array by 4, placing 4 columns in
    > each quadrant, but I can't figure out the math logic to alter it for my
    > needs above.
    >
    > Any additional help you can offer would be absolutely awesome and would
    > almost require me to send a keg ;).
    Okay, first, just have to ask this question: Are we doing this in the
    best way we possibly can? What about something like this?

    my @data;
    my @headers = split /;/, scalar <DATAFILE>;
    while (<DATAFILE>) {
    chomp;
    my @fields = split /;/, $_;
    foreach (@fields) { s/^\s+//; s/\s+$//; }
    push @data, { map { ($header[$_], $fields[$_]) } 0..$#headers };
    }

    print Dumper(\@data); # so you can see what it makes...

    Okay, enough with my tangent. I'll assume you know what you want and
    we'll give that a go. Let's change it up a little though, to make my
    life easier, which is all we really care about ;) :

    my %quads = ( quad1 => [ ],
    quad2 => [ ],
    quad3 => [ ],
    quad4 => [ ] );
    while (<DATAFILE>) {
    chomp;
    my @fields = split /;/, $_;
    foreach (@fields) { s/^\s+//; s/\s+$//; }
    push @{ $quads{quad1} }, [ @fields[ 0..7 ] ];
    push @{ $quads{quad2} }, [ @fields[ 8..14 ] ];
    # I didn't understand the spec perfectly, so you probably need to fix
    # the following push() where I mostly guessed
    push @{ $quads{quad3} }, [ @fields[ 0, 8..14 ] ];
    push @{ $quads{quad4} }, [ @fields[ 15..18 ] ];
    }

    print Dumper(\%quads); # just to show what we have here

    # or we can keep going to get back to the array you asked for...

    my @array_2d = @{ $quads{quad1} };
    for (my $i = 0; $i < @array_2d; $i++) {
    push @{ $array_2d[$i] }, undef, @{ $quads{quad2}[$i] };
    }
    push @array_2d, [ ];
    push @array_2d,
    map { [ @{ $quads{quad3}[$_] }, undef, @{ $quads{quad4}[$_] } ] }
    0..$#{ $quads{quad3} };

    print Dumper(\@array_2d); # I believe that gets us back to where you
    wanted to go

    Hopefully there's some wisdom buried in all that array mumbo jumbo that
    will help you along, Good luck.

    James

    James Edward Gray II Guest

  12. #11

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Thu, 2003-10-16 at 17:53, James Edward Gray II wrote:
    > On Thursday, October 16, 2003, at 03:25 PM, Kevin Old wrote:
    >
    > > James, is it possible to ask for a little more help with this?
    >
    > Nope, you've used up all your free answer tokens. <laughs> Oh,
    > alright, just this once...
    Help with my script AND Comedy! Folks, don't forget to tip your
    waitress... <grin>
    >
    > > Here's the actual data I'm parsing (it's padded with spaces, but dont'
    > > worry about them) and delimited by semicolon's.
    >
    > Ah, the Real-Question-Switcheroo! ;)
    Yeah, sorry about that.....I've learned my lesson....from now on, the
    data goes in the first post. :D
    > Okay, first, just have to ask this question: Are we doing this in the
    > best way we possibly can? What about something like this?
    >
    > my @data;
    > my @headers = split /;/, scalar <DATAFILE>;
    > while (<DATAFILE>) {
    > chomp;
    > my @fields = split /;/, $_;
    > foreach (@fields) { s/^\s+//; s/\s+$//; }
    > push @data, { map { ($header[$_], $fields[$_]) } 0..$#headers };
    > }
    >
    > print Dumper(\@data); # so you can see what it makes...
    >
    Not sure I got your point. The data didn't have the look I needed.

    > Okay, enough with my tangent. I'll assume you know what you want and
    > we'll give that a go. Let's change it up a little though, to make my
    > life easier, which is all we really care about ;) :
    >
    > my %quads = ( quad1 => [ ],
    > quad2 => [ ],
    > quad3 => [ ],
    > quad4 => [ ] );
    > while (<DATAFILE>) {
    > chomp;
    > my @fields = split /;/, $_;
    > foreach (@fields) { s/^\s+//; s/\s+$//; }
    > push @{ $quads{quad1} }, [ @fields[ 0..7 ] ];
    > push @{ $quads{quad2} }, [ @fields[ 8..14 ] ];
    > # I didn't understand the spec perfectly, so you probably need to fix
    > # the following push() where I mostly guessed
    > push @{ $quads{quad3} }, [ @fields[ 0, 8..14 ] ];
    > push @{ $quads{quad4} }, [ @fields[ 15..18 ] ];
    Yes, this is almost what I need, but instead of the headers being in the
    first column, I need the in the first row.

    Here's an example I put together to build the first quad.
    open (DATAFILE, "mthsum") or die "Can't open file $!\n";

    my @tmp = ();
    my $i = 0;
    while(<DATAFILE>) {
    chomp;
    my $j = 0;
    my @fields = split /;/, $_;
    foreach (@fields) { s/^\s+//; s/\s+$//; }
    #push @tmp, [ @fields[0..7] ];
    foreach ( @fields[ 0..7 ] ) { # any idea
    $tmp[$j][$i] = $_; # if there's a better
    $j++; # way to write this
    } # maybe without the $i and $j
    $i++; # or as a push ???
    }

    print "$tmp[2][0]\n"; # result is STD REPL SHIPPED

    > }
    >
    > print Dumper(\%quads); # just to show what we have here
    >
    > # or we can keep going to get back to the array you asked for...
    >
    > my @array_2d = @{ $quads{quad1} };
    > for (my $i = 0; $i < @array_2d; $i++) {
    > push @{ $array_2d[$i] }, undef, @{ $quads{quad2}[$i] };
    > }
    > push @array_2d, [ ];
    > push @array_2d,
    > map { [ @{ $quads{quad3}[$_] }, undef, @{ $quads{quad4}[$_] } ] }
    > 0..$#{ $quads{quad3} };
    >
    > print Dumper(\@array_2d); # I believe that gets us back to where you
    Yes, this part is perfect.

    James, again I sincerely appreciate your help with this script and am
    once again awed by the open source community and the lengths some will
    go to help others, no matter how complex and confusing the situation is.

    Thanks so very much!

    Kevin

    --
    Kevin Old <kold@kold.homelinux.com>

    Kevin Old Guest

  13. #12

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Friday, October 17, 2003, at 10:15 AM, Kevin Old wrote:
    > Help with my script AND Comedy! Folks, don't forget to tip your
    > waitress... <grin>
    Thank ya. I'll be here all week. :P
    >> On Thu, 2003-10-16 at 17:53, James Edward Gray II wrote:
    >>
    >> Okay, first, just have to ask this question: Are we doing this in the
    >> best way we possibly can? What about something like this?
    >>
    >> my @data;
    >> my @headers = split /;/, scalar <DATAFILE>;
    >> while (<DATAFILE>) {
    >> chomp;
    >> my @fields = split /;/, $_;
    >> foreach (@fields) { s/^\s+//; s/\s+$//; }
    >> push @data, { map { ($header[$_], $fields[$_]) } 0..$#headers };
    >> }
    >>
    >> print Dumper(\@data); # so you can see what it makes...
    >>
    >
    > Not sure I got your point. The data didn't have the look I needed.
    You're right, it didn't. That was just my way of giving some other
    ideas of possibly useful ways to look at that kind of data. I was just
    making sure you knew what you wanted, which you clearly do. I find
    your quadrant divided array a little hard to follow, which doesn't
    matter at all, but I was just making sure there wasn't an easier way.
    Feel free to ignore me, it works fine for my mother.
    > Yes, this is almost what I need, but instead of the headers being in
    > the
    > first column, I need the in the first row.
    Add a:

    <DATAFILE>;

    before the while loop to throw away the headers. I think that's what
    you meant.
    > Here's an example I put together to build the first quad.
    > open (DATAFILE, "mthsum") or die "Can't open file $!\n";
    >
    > my @tmp = ();
    > my $i = 0;
    > while(<DATAFILE>) {
    > chomp;
    > my $j = 0;
    > my @fields = split /;/, $_;
    > foreach (@fields) { s/^\s+//; s/\s+$//; }
    > #push @tmp, [ @fields[0..7] ];
    > foreach ( @fields[ 0..7 ] ) { # any idea
    > $tmp[$j][$i] = $_; # if there's a better
    > $j++; # way to write this
    > } # maybe without the $i and $j
    > $i++; # or as a push ???
    > }
    >
    > print "$tmp[2][0]\n"; # result is STD REPL SHIPPED
    Egad, scratch what I said before because that's obviously not what you
    meant! You like pain don't you man? <laughs>

    Alright, let's plan this out a little. You have a piece of working
    code above. Good start. By the way, don't sweat making two variables,
    if it works, it works. You might call them $x and $y though, to make
    it a little easier to follow.

    Back to our plan. You ARE making the first quadrant correctly. Now if
    we put that in the @{ $quads{quad1} } from my example, we're a fourth
    of the way there right? We could rework the above loop to add them
    there instead or if we're truly lazy we could add a:

    @{ $quads{quad1} } = @tmp;

    just after the loop, eh?

    Now for the other three quads. Could you whip up loops for them too?
    I suspect you could since it's pretty much the exact same thing. Then
    if we load them into the appropriate arrays from my example too, my
    "prefect" code below finishes up the problem, right? How's that?

    Aside: Is this the perfect way to code it up? Probably not. If you
    do it just as I said, you'll have to read the data four times, which
    won't be super zippy. However it IS using what we know and it IS a
    functional solution from a simple plan, right? Don't underestimate
    that. Once you have a solution, you could work on combining the loops,
    right? You give that version to management with a speech about "a four
    times increase in efficiency" and "your Cyber Ninja coding skills" are
    you're a bloody hero. What's not to like about that? It's a short
    step from there to being a hit with the ladies, we hope, and then...
    Oh, you get the idea. ;)

    Now, if that sounds adventurous, skip this next chunk of code and have
    at it Cyber Ninja! If instead you're thinking, "Is this guy ever going
    to solve my freakin' problem or what?", read on...

    my %quads = { quad1 => [ ],
    quad2 => [ ],
    quad3 => [ ],
    quad4 => [ ] };
    while (<DATAFILE>) {
    chomp;
    my @fields = split /;/, $_;
    foreach (@fields) { s/^\s+//; s/\s+$//; }
    my @quad1 = @fields[0..7];
    my @quad2 = @fields[8..14]
    my @quad3 = @fields[0, 8..14];
    my @quad4 = @fields[15..18];
    # I'm not ashamed of using many variables to save my sanity!
    if (not @{ $quads{quad1} }) {
    @{ $quads{quad1} } } = map { [ $_ ] } @quad1;
    @{ $quads{quad2} } } = map { [ $_ ] } @quad2;
    @{ $quads{quad3} } } = map { [ $_ ] } @quad3;
    @{ $quads{quad4} } } = map { [ $_ ] } @quad4;
    }
    else {
    push @$_, shift @quad1 foreach @{ $quads{quad1} } };
    push @$_, shift @quad2 foreach @{ $quads{quad2} } };
    push @$_, shift @quad3 foreach @{ $quads{quad3} } };
    push @$_, shift @quad4 foreach @{ $quads{quad4} } };
    }
    # yes, the above can be simplified a lot, if it bothers you
    # but that is left as an exercise to the reader
    }
    >> # or we can keep going to get back to the array you asked for...
    >>
    >> my @array_2d = @{ $quads{quad1} };
    >> for (my $i = 0; $i < @array_2d; $i++) {
    >> push @{ $array_2d[$i] }, undef, @{ $quads{quad2}[$i] };
    >> }
    >> push @array_2d, [ ];
    >> push @array_2d,
    >> map { [ @{ $quads{quad3}[$_] }, undef, @{ $quads{quad4}[$_] } ] }
    >> 0..$#{ $quads{quad3} };
    >>
    >> print Dumper(\@array_2d); # I believe that gets us back to where you
    >
    > Yes, this part is perfect.
    Damn, I overshot. I was aiming for just good enough. <laughs>
    > James, again I sincerely appreciate your help with this script and am
    > once again awed by the open source community and the lengths some will
    > go to help others, no matter how complex and confusing the situation
    > is.
    >
    > Thanks so very much!
    Anytime. Perl's community is one of its great advantages, in my
    opinion. People on this list helped me so much when I was just getting
    started, I'm glad I can sometimes do the same. Your time will come...
    ;)

    James

    James Edward Gray II Guest

  14. #13

    Default Re: Split multidimensional array into 4 multidimensional arrays

    Hi James,

    In article <AC9AA3E4-00D1-11D8-A2FF-0003930388F0@grayproductions.net>, James
    Edward Gray II wrote:
    [...]
    > my %quads = { quad1 => [ ],
    > quad2 => [ ],
    > quad3 => [ ],
    > quad4 => [ ] };
    I _think_ you meant to use parens and not curly brackets:
    my %quads = ( quad1 => [ ],
    quad2 => [ ],
    quad3 => [ ],
    quad4 => [ ]
    );
    > while (<DATAFILE>) {
    > chomp;
    > my @fields = split /;/, $_;
    > foreach (@fields) { s/^\s+//; s/\s+$//; }
    > my @quad1 = @fields[0..7];
    > my @quad2 = @fields[8..14]
    > my @quad3 = @fields[0, 8..14];
    > my @quad4 = @fields[15..18];
    > # I'm not ashamed of using many variables to save my sanity!
    > if (not @{ $quads{quad1} }) {
    > @{ $quads{quad1} } } = map { [ $_ ] } @quad1;
    > @{ $quads{quad2} } } = map { [ $_ ] } @quad2;
    > @{ $quads{quad3} } } = map { [ $_ ] } @quad3;
    > @{ $quads{quad4} } } = map { [ $_ ] } @quad4;
    > }
    > else {
    > push @$_, shift @quad1 foreach @{ $quads{quad1} } };
    > push @$_, shift @quad2 foreach @{ $quads{quad2} } };
    > push @$_, shift @quad3 foreach @{ $quads{quad3} } };
    > push @$_, shift @quad4 foreach @{ $quads{quad4} } };
    > }
    > # yes, the above can be simplified a lot, if it bothers you
    > # but that is left as an exercise to the reader
    > }

    --
    Kevin Pfeiffer
    International University Bremen

    Kevin Pfeiffer Guest

  15. #14

    Default Re: Split multidimensional array into 4 multidimensional arrays

    In article <AC9AA3E4-00D1-11D8-A2FF-0003930388F0@grayproductions.net>, James
    Edward Gray II wrote:
    [...]
    > On Friday, October 17, 2003, at 10:15 AM, Kevin Old wrote:
    [...]
    >> Yes, this is almost what I need, but instead of the headers being in
    >> the first column, I need the in the first row.
    [...]


    This is my new version (with headers in first column for each).
    Improvements/advice welcome...

    my %array_ref;

    while (<DATA>) {
    next if /^#.*/;
    chomp;
    my @fields = split /\s*;\s*/, $_;

    push @{$array_ref{1}}, [ @fields[0..7] ];
    push @{$array_ref{2}}, [ @fields[8..14] ];
    push @{$array_ref{3}}, [ @fields[0, 8..14] ];
    push @{$array_ref{4}}, [ @fields[15..18] ];

    }

    # use Data::Dumper;
    # print Dumper(\%array_ref);
    # exit;

    foreach my $nbr (sort keys %array_ref) {
    print "Array $nbr\:\n";

    # loops through ea. array
    foreach (@{ $array_ref{$nbr} }) {

    # prints formatted row
    foreach my $col (@{$_}) {
    printf "%16s|", $col;
    }
    print "\n";
    }
    }



    -Kevin

    --
    Kevin Pfeiffer
    International University Bremen

    Kevin Pfeiffer Guest

  16. #15

    Default Re: Split multidimensional array into 4 multidimensional arrays

    On Saturday, October 18, 2003, at 03:12 AM, Kevin Pfeiffer wrote:
    > Hi James,
    >
    > In article <AC9AA3E4-00D1-11D8-A2FF-0003930388F0@grayproductions.net>,
    > James
    > Edward Gray II wrote:
    > [...]
    >> my %quads = { quad1 => [ ],
    >> quad2 => [ ],
    >> quad3 => [ ],
    >> quad4 => [ ] };
    >
    > I _think_ you meant to use parens and not curly brackets:
    > my %quads = ( quad1 => [ ],
    > quad2 => [ ],
    > quad3 => [ ],
    > quad4 => [ ]
    > );
    You're very right. Good catch.

    James

    James Edward Gray II Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139