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

Hello,

I need help on multidimensional array:

I'm using this code to update the array and print it out

push (@Cdevices, $UnitID, $fileno); push (@Mdevices, \@Cdevices); for ($k=0; $k<=$#Mdevices; $k++) { print $Mdevices[$k][0],"\n"; } $k=0;

I want to print all UnitID's from Mdevices array
But it always prints out only the first record from my Mdevices

Do you know, what I'm doing wrong?

Thanks in advance!

Igor

Replies are listed 'Best First'.
Re: Multidimensional array
by svenXY (Deacon) on Dec 10, 2008 at 13:48 UTC
    Hi,
    because you explicitely ask for the first element $Mdevices[$k][0]. You can get proper access to all elements by dereferencing properly:
    #!/usr/bin/perl use strict; use warnings; my (@Cdevices,@Mdevices); push (@Cdevices, 'UnitID', 'fileno'); push (@Mdevices, \@Cdevices); # this will show us the actual layout of the array use Data::Dumper; print Dumper(\@Mdevices); # $k=0; $k<=$#Mdevices; $k++ is C-style. Possible, but unnecessary ove +rhead for my $ref (@Mdevices) { print join(' - ', @{$ref}),"\n"; }
    prints
    $VAR1 = [ [ 'UnitID', 'fileno' ] ]; UnitID - fileno
    update: after reading the OP again, it now becomes a bit more clear to me what he actually wants to do and I also found out what the problem is. Look at the following code:
    my (@Cdevices,@Mdevices); push (@Cdevices, 'UnitID1', 'fileno1'); push (@Cdevices, 'UnitID2', 'fileno2'); # <- @Cdevices is now qw(UnitI +D1 fileno1 UnitID2 fileno2) push (@Cdevices, 'UnitID3', 'fileno3'); # <- and so on push (@Mdevices, \@Cdevices); # this makes it clear: use Data::Dumper; print Dumper(\@Cdevices); print Dumper(\@Mdevices); for my $ref (@Mdevices) { print $ref->[0],"\n"; }
    You want the first element of each sub-array, but there is only one sub-array!!! you would need something like this: push (@Cdevices, ['UnitID3', 'fileno3']); # that will store a reference to an anonymous array
    Regards,
    svenXY

      Indeed. The fragment offered can be fixed...

      push (@Mdevices, [$UnitID, $fileno]); for ($k=0; $k<=$#Mdevices; $k++) { print $Mdevices[$k][0],"\n"; } $k=0;
      ...the named @Cdevices is not required.

      If the more complete code is along the lines:

      my @Mdevices ; my @Cdevices ; while (... something ...) { ... do something to get $UnitID & $fileno ... push (@Cdevices, $UnitID, $fileno); ... do some other stuff ... push (@Mdevices, \@Cdevices); } ;
      then @Mdevices is going to end up with 'n' copies of a reference to @Cdevices, which contains a list of the 'n' $UnitID and $fileno seen.

      Whereas the almost identical:

      my @Mdevices ; while (... something ...) { my @Cdevices ; ... do something to get $UnitID & $fileno ... push (@Cdevices, $UnitID, $fileno); ... do some other stuff ... push (@Mdevices, \@Cdevices); } ;
      fills @Mdevices with 'n' references to 'n' different annonymous arrays, each containing a $UnitID and $fileno pair.

      Obvious, really.

      Alternatively:

      my @Mdevices ; while (... something ...) { ... do something to get $UnitID & $fileno ... ... do some other stuff ... push (@Mdevices, [$UnitID, $fileno]); } ;
      will do the trick -- unless the @Cdevices array is required in the loop.

        Hello!

        This code really did the trick!

        my @Mdevices ; while (... something ...) { ... do something to get $UnitID & $fileno ... ... do some other stuff ... push (@Mdevices, [$UnitID, $fileno]); } ;

        Thanks to all of you for help

        Igor

Re: Multidimensional array
by toolic (Bishop) on Dec 10, 2008 at 13:51 UTC
    Maybe Mdevices only has one record in it? You only show a single push of an array reference into it. You can use Data::Dumper to help visualize your data structures.
    use Data::Dumper; print Dumper(\@Cdevices); print Dumper(\@Mdevices);

    This may also be of use: References quick reference

Re: Multidimensional array
by Bloodnok (Vicar) on Dec 10, 2008 at 13:45 UTC
    The array @Mdevices is constructed as an array of array refs, so you should de-reference using e.g. print $Mdevices[$k]->[0],"\n"; - something that the use of strictures would have pointed out for you.

    A user level that continues to overstate my experience :-))
      you should de-reference using e.g. print $Mdevices[$k]->[0]

      $Mdevices[$k]->[0] is functionally the same as $Mdevices[$k][0] (what the OP had).  You only need the arrow if it's at the 'first' level (i.e. $Mdevices->[0] is not the same as $Mdevices[0] — here, the parser needs some way to disambiguate). In case it isn't ambiguous (between brackets/braces), the arrow is optional.

        TFT almut, the old saying about a day learning nothing is a day lost just came home to roost - that's another tool for my toolbox.

        It also underlines my sig, doncha think ?

        A user level that continues to overstate my experience :-))
Re: Multidimensional array
by GrandFather (Saint) on Dec 10, 2008 at 23:12 UTC

    oshalla has addressed your coding error, but if you intend to further your Perl programming skills there are a couple of other things you did "wrong".

    First, always use strictures (use strict; use warnings;).

    Write Perl not C. In particular, Perl for loops are much safer and clearer than C for loops. Consider:

    for ($k=0; $k<=$#Mdevices; $k++) { print $Mdevices[$k][0],"\n"; } for my $device (@Mdevices) { print $device->[0], "\n"; }

    In fact a slightly more experienced Perl programmer would use a for statement modifier and the loop becomes:

    print $_->[0], "\n" for @Mdevices;

    In PerlMonks terms what you did wrong was to not show a runnable sample the demonstrates the problem. The code you provided doesn't show the problem that oshalla (using his elite esp skills) resolved for you. However if you had instead shown us:

    for (1 ..5) { push (@Cdevices, "UnitId$_", $_); push (@Mdevices, \@Cdevices); } print $_->[0], "\n" for @Mdevices;

    prints:

    UnitId1 UnitId1 UnitId1 UnitId1 UnitId1

    and told us what you expected to see instead we'd have known what the problem was straight off.


    Perl's payment curve coincides with its learning curve.