LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-18-2009, 09:58 AM   #1
zhjim
Senior Member
 
Registered: Oct 2004
Distribution: Debian Squeeze x86_64
Posts: 1,748
Blog Entries: 11

Rep: Reputation: 233Reputation: 233Reputation: 233
Perl multidimensional array


Hi folks,

right now I need to develop a bit of shell script that evaluates parts of apache logs but am stuck. I have the parsing done and now want to fill an array uniqly with page names and sum up the time taken for the request. Heres how i planed it

PHP Code:
#whereis perl
my @parts;
while ( <
APACHE> ) {
    ....
    
# call function to put the vars into the array
    
adduniq$page$time );
    ....
}
sub adduniq{
my $page $_[0];
my $time $_[1];
    foreach 
my $part( @parts ){
         if ( 
$part[0eq $page ){
             
$part[1] += $time;
             
$part[2]++;
             return 
0;
         }

    }
    @new = (
$page$time);
    
push( @parts, @new );

Problem here is that the elements of the @new array get pushed into the @parts array and not the @new array as a whole.
Anyone here that can shed some light on multidimensional arrays in perl?

Thanks in advance
Zhjim
 
Old 08-18-2009, 10:58 AM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by zhjim View Post
Hi folks,

right now I need to develop a bit of shell script that evaluates parts of apache logs but am stuck. I have the parsing done and now want to fill an array uniqly with page names and sum up the time taken for the request. Heres how i planed it

PHP Code:
#whereis perl
my @parts;
while ( <
APACHE> ) {
    ....
    
# call function to put the vars into the array
    
adduniq$page$time );
    ....
}
sub adduniq{
my $page $_[0];
my $time $_[1];
    foreach 
my $part( @parts ){
         if ( 
$part[0eq $page ){
             
$part[1] += $time;
             
$part[2]++;
             return 
0;
         }

    }
    @new = (
$page$time);
    
push( @parts, @new );

Problem here is that the elements of the @new array get pushed into the @parts array and not the @new array as a whole.
Anyone here that can shed some light on multidimensional arrays in perl?

Thanks in advance
Zhjim
http://perldoc.perl.org/perlreftut.html
 
Old 08-18-2009, 12:26 PM   #3
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
@Zhjim: Sergei's recommendation is very good. You can also get that tutorial via your internal Perl documentation at perldoc perlreftut. However, you are very close in your code above. The key thing you're not doing is taking a reference to the item you push into the @parts array. As a result, you are getting a flattened list, not an array of arrays. Here's a silly script that shows two different ways you can take a reference to the array as you push it into another array:

Code:
#!/usr/bin/env perl
use strict;
use warnings;

my @AoA;

for my $num (1..100) {
  for my $let ('A'..'Z') {
    my @combo;
    push @combo, $let . $num, $num . $let;
    push @AoA, [ @combo ]; # This way works great
    #push @AoA, \@combo;   # So does this way
  }
}

use Data::Dumper;
print Dumper \@AoA;
You might also take a look at perldoc perldsc for a good cookbook style presentation of how to create multi-dimensional structures of all kinds with Perl.
 
Old 08-18-2009, 01:47 PM   #4
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Telemachos View Post
@Zhjim: Sergei's recommendation is very good. You can also get that tutorial via your internal Perl documentation at perldoc perlreftut. However, you are very close in your code above. The key thing you're not doing is taking a reference to the item you push into the @parts array. As a result, you are getting a flattened list, not an array of arrays. Here's a silly script that shows two different ways you can take a reference to the array as you push it into another array:

Code:
#!/usr/bin/env perl
use strict;
use warnings;

my @AoA;

for my $num (1..100) {
  for my $let ('A'..'Z') {
    my @combo;
    push @combo, $let . $num, $num . $let;
    push @AoA, [ @combo ]; # This way works great
    #push @AoA, \@combo;   # So does this way
  }
}

use Data::Dumper;
print Dumper \@AoA;
You might also take a look at perldoc perldsc for a good cookbook style presentation of how to create multi-dimensional structures of all kinds with Perl.
I haven't looked closely into the code, but the good question is whether a multidimensional array is indeed needed.

In Perl multidimensional array is indeed needed when sub-arrays have different and unknown beforehand number of elements, e.g.:

Code:
...
$arr[0] = [1, 2, 3];
...
$arr[3] = [5, 6, 7, 8, 9];
...
If number of elements in sub-arrays is constant and known, then unidimensional array is fine and probably is more efficient. e.g.:

Code:
my @arr; # 3 elements per portion
push @arr, (1, 2, 3); # portion 0
push @arr, (4, 5, 6); # portion 1

# '3' below is number of elements in portion, '1' below is portion number, '2' below is element number in the portion
warn $arr[3 * 1 + 2]; # will print 6
.

I often use this 1-d optimization if the conditions allow, even though I have no problems with Perl references/multidimensional arrays. And/or in other words I effectively do what "C" compiler does with multidimensional arrays in "C".
 
Old 08-21-2009, 05:55 AM   #5
zhjim
Senior Member
 
Registered: Oct 2004
Distribution: Debian Squeeze x86_64
Posts: 1,748

Original Poster
Blog Entries: 11

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by Sergei Steshenko
I haven't looked closely into the code, but the good question is whether a multidimensional array is indeed needed.

In Perl multidimensional array is indeed needed when sub-arrays have different and unknown beforehand number of elements, e.g.:
After reading through the link in your first post I rethought my approach and jup I don't need no multidimensional array. dunno what i thought in the first place.
The link you gave is very nice. Also I'm not quite sure if I already have perl 5 installed.


@Telemachos:
Nice sum up of ways that work and don't.

I'll just try both ways. One with an multidimsional array and one with just plain array. Will make a good training.


Thanks to the both of you.

Cheers Zhjim
 
Old 08-21-2009, 06:32 AM   #6
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
Quote:
Originally Posted by zhjim View Post
Also I'm not quite sure if I already have perl 5 installed.
If you don't have at least Perl 5 (I would even say 5.6), you really must upgrade if at all possible.
 
Old 08-21-2009, 07:22 AM   #7
zhjim
Senior Member
 
Registered: Oct 2004
Distribution: Debian Squeeze x86_64
Posts: 1,748

Original Poster
Blog Entries: 11

Rep: Reputation: 233Reputation: 233Reputation: 233
I always like to stay inside the package managers default packages. As the box I'm doing this on is RH 4 I think I'm blocked. Don't want to break things.
Any special reason to get the perl 5.+ version? Or is it just for the features?
 
Old 08-21-2009, 08:18 AM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by zhjim View Post
I always like to stay inside the package managers default packages. As the box I'm doing this on is RH 4 I think I'm blocked. Don't want to break things.
Any special reason to get the perl 5.+ version? Or is it just for the features?
One can build perl-5.10.0 in whatever directory he/she likes, and the newly built Perl thus will peacefully coexist with system one not breaking anything.
 
Old 08-21-2009, 08:20 AM   #9
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by zhjim View Post
...
I'm not quite sure if I already have perl 5 installed.
...
No doubt whatsoever you have Perl 5 installed. Perl 5 appeared in 1993 or so. You will have to make a special non-trivial effort to have Perl 4 installed.
 
Old 08-21-2009, 10:59 AM   #10
zhjim
Senior Member
 
Registered: Oct 2004
Distribution: Debian Squeeze x86_64
Posts: 1,748

Original Poster
Blog Entries: 11

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by Sergei Steshenko View Post
No doubt whatsoever you have Perl 5 installed. Perl 5 appeared in 1993 or so. You will have to make a special non-trivial effort to have Perl 4 installed.
Just checked on the version. perl gave me 5.8.5. So I'm off the hook. Also I thought perl 5 is a bit younger. so another point for "the older the lady the nicer the juice"

Cheers Zhjim
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
JAVA: creating a multidimensional array Garda Programming 5 08-10-2007 07:15 AM
How to allocate memory for a multidimensional array ? indian Programming 12 11-19-2004 04:37 AM
return index of element in java multidimensional array dave bean Programming 8 11-28-2003 12:00 PM
multidimensional array (php) niehls Programming 2 01-31-2003 06:34 AM
PHP: Multidimensional array problem lhoff Programming 1 06-10-2002 03:49 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:18 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration