0

Hi I have a array as myarray. I would like to make a list as '1 2 3' which is joining the first subarray. My string is printing the memory location I suppose instead of list. any help will be appreciated.

@myarray = [[1,2,3],[4,5,6],[7,8,9]];
for (my $i=0; $i < @myarray; $i++) {
my @firstarray = $myarray[$i];
my $mystring = join("", @firstarray);
print "My string ".$mystring . ". "\n";
}
Axeman
  • 29,660
  • 2
  • 47
  • 102
mysteriousboy
  • 159
  • 1
  • 7
  • 20
  • Learn about Perl references and dereferencing. Contrary to popular belief, they're almost totally unlike C-style pointers, and you are doing some strange things with them in your example. The following Perl tutorial gives the most concise treatment of the subject I know: http://qntm.org/files/perl/perl.html – Zac B Mar 18 '13 at 21:19
  • `use warnings;` -- that would have alerted you to your strange initialization for `@myarray` – mob Mar 18 '13 at 22:12
  • 1
    for references I prefer the core document [perldoc perlreftut](http://p3rl.org/reftut). It makes references much more understandable. – Joel Berger Mar 18 '13 at 23:45

5 Answers5

4

You should use the Data::Dumper module, that way, that will help you to know how to parse your data structure :

print Dumper \@myarray; # force passing array as ref
$VAR1 = [
          [
            [
              1,
              2,
              3
            ],
            [
              4,
              5,
              6
            ],
            [
              7,
              8,
              9
            ]
          ]
        ];

But using the @ sigil (array) to store an ARRAY ref is strange, a $ sigil (scalar) is used most of the times for that purpose. (a reference is like a C pointer : an address to a memory cell. So its' a simple string, no need something else than a scalar to store it)

Then, you need to de-reference with the -> operator.

Ex :

$ perlconsole
Perl Console 0.4

Perl> my $arrayref = [[1,2,3],[4,5,6],[7,8,9]];

Perl> print join "\n", @{ $arrayref->[2] }
7
8
9
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
4

You have to dereference the inner array reference by @{ ... }. Also, do not use [...] for the top structure - use normal parentheses (square brackets create an array reference, not an array). There was also a problem with the concatenation on your print line:

@myarray = ( [1,2,3], [4,5,6], [7,8,9] );
for (my $i=0; $i < @myarray; $i++) {
    my @firstarray = @{ $myarray[$i] };
    my $mystring = join("", @firstarray);
    print "My string " . $mystring . ".\n";
}
choroba
  • 231,213
  • 25
  • 204
  • 289
2

You actually have an array of array of array.

  • The outer array has one element, a reference to an array.
    $myarray[0]
  • That referenced array has three elements, each a reference to an array.
    $myarray[0][0..2]
  • Each of those referenced arrays have three elements, three numbers.
    $myarray[0][0..2][0..2]

You want

my @aoa = ([1,2,3],[4,5,6],[7,8,9]);
   ^       ^       ^       ^
   |        \------+------/
   |            3 inner
1 outer

$aoa[$i][$j]

for my $inner (@aoa) {
   print(join(', ', @$inner), "\n");
}

or

my $aoa = [[1,2,3],[4,5,6],[7,8,9]];
          ^^       ^       ^
          | \------+------/
          |      3 inner
       1 outer

$aoa->[$i][$j]

for my $inner (@$aoa) {
   print(join(', ', @$inner), "\n");
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • why is it an "array of array of array"? i see an outer array or three inner single-dimensional arrays – amphibient Mar 18 '13 at 21:11
  • @amphibient, Because you have 3 arrays referenced by elements of one array referenced by elements of one array. That's 5 arrays, not 4. As I showed, count the `my @` and the `[]`. Remember that `[...]` is basically `do { my @a = (...); \@a }`. – ikegami Mar 18 '13 at 21:26
  • but if you have 3 inner and one outer, that is 4 arrays, no? besides, i would just look at it as a simple `AoA [3][3]` – amphibient Mar 18 '13 at 21:27
  • @amphibient, Yes, if you had 3 inner and one outer, that would be 4. Since he has 5 (one created with `my` and 4 created with `[]`), he doesn't have 3 inner and one outer. This can also bee seen with `Dumper(\@myarray)`. – ikegami Mar 18 '13 at 21:32
  • ah, OK -- so you are saying that, the way he declares it, he has 5, whereas he is supposed to correctly have 4 – amphibient Mar 18 '13 at 21:34
  • @amphibient, Yup. He's got an AoAoA when he wants an AoA. – ikegami Mar 18 '13 at 21:34
1

You need to change how you initialize your array so that () is used for the outer array bounds and [] for the inner arrays, which means that they are declared as references that will later need to be cast into their native array format for processing (my @subarray = @{$myarray[$i]};)

my @myarray = ([1,2,3], [4,5,6], [7,8,9]);

for (my $i=0; $i < @myarray; $i++) 
{
    my @subarray = @{$myarray[$i]};
    my $subarrayStr = join("", @subarray);
    print $i.". Subarray Str = ".$subarrayStr."\n";
}
amphibient
  • 29,770
  • 54
  • 146
  • 240
0
$myarray = [[1,2,3],[4,5,6],[7,8,9]];
printf "My string %s\n", join(" ", @{$myarray->[0]});

[[1,2,3],[4,5,6],[7,8,9]] returns a reference to the list of lists, not a list.

Change the @ into $ , to make $myarray a variable.

@{$myarray->[0]} will dereference the first sublist and return you the list you can use.

To print all three lists:

$myarray = [[1,2,3],[4,5,6],[7,8,9]];
map{printf "My string %s\n", join(" ",@{$_})} @{$myarray};
drjors
  • 69
  • 1
  • 3