For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > May 2006 > Work with first x number of elements in array









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Work with first x number of elements in array
Greg John ** CTR ** Keenan

2006-05-25, 6:58 pm

Hi,

What is the best way to only work with the first x number of elements in an
array?

At the moment this script prints the entire contents of @lines for each
element in @cfgs

I would like to restrict this to the number of elements listed in the hash
%numTapes for each element in @cfgs

Any suggestions for improving this script much appreciated.

Thanks,
Greg.


--start--
use strict;
use warnings;

my $cfgDir = '/amanda/admin/etc/amanda';
my @cfgs = qw(Toaster MFG-UNIX SYS-UNIX Amanda-Daily);
my %numTapes = (
"$cfgs[0]" => 6,
"$cfgs[1]" => 5,
"$cfgs[2]" => 5,
"$cfgs[3]" => 1,
);

my $cfg;
foreach $cfg (@cfgs) {
my $fileIn="$cfgDir/$cfg/tapelist";
open (FILEIN, "<$fileIn") or die ("Could not open $fileIn: $!");
my @lines = reverse <FILEIN>;
my $line;
foreach $line (@lines) {
print "$line\n";
}
}
--end--

John W. Krahn

2006-05-25, 6:58 pm

Keenan, Greg John (Greg)** CTR ** wrote:
> Hi,


Hello,

> What is the best way to only work with the first x number of elements in an
> array?
>
> At the moment this script prints the entire contents of @lines for each
> element in @cfgs
>
> I would like to restrict this to the number of elements listed in the hash
> %numTapes for each element in @cfgs
>
> Any suggestions for improving this script much appreciated.
>
>
> --start--
> use strict;
> use warnings;
>
> my $cfgDir = '/amanda/admin/etc/amanda';
> my @cfgs = qw(Toaster MFG-UNIX SYS-UNIX Amanda-Daily);
> my %numTapes = (
> "$cfgs[0]" => 6,
> "$cfgs[1]" => 5,
> "$cfgs[2]" => 5,
> "$cfgs[3]" => 1,
> );


Do you really need an array and a hash? If you need keep the order of @cfgs
you could use an array of arrays:

my @cfgs = (
[ Toaster => 6 ],
[ MFG-UNIX => 5 ],
[ SYS-UNIX => 5 ],
[ Amanda-Daily => 1 ],
);

If you don't really care about the order then just use a hash:

my %cfgs = (
Toaster => 6,
MFG-UNIX => 5,
SYS-UNIX => 5,
Amanda-Daily => 1,
);


> my $cfg;
> foreach $cfg (@cfgs) {
> my $fileIn="$cfgDir/$cfg/tapelist";
> open (FILEIN, "<$fileIn") or die ("Could not open $fileIn: $!");
> my @lines = reverse <FILEIN>;
> my $line;
> foreach $line (@lines) {
> print "$line\n";
> }
> }


Using an AoA:

for my $cfg ( @cfgs ) {
my $fileIn = "$cfgDir/$cfg->[0]/tapelist";
open FILEIN, '<', $fileIn or die "Could not open $fileIn: $!";
print +( reverse <FILEIN> )[ -$cfg->[1] .. -1 ];
}

Using a hash:

for my $cfg ( keys %cfgs ) {
my $fileIn = "$cfgDir/$cfg/tapelist";
open FILEIN, '<', $fileIn or die "Could not open $fileIn: $!";
print +( reverse <FILEIN> )[ -$cfg{$cfg} .. -1 ];
}


Also, if the files are large you can get better efficiency using the
File::ReadBackwards module.



John
--
use Perl;
program
fulfillment
John W. Krahn

2006-05-25, 6:58 pm

Joshua Colson wrote:
> On Fri, 2006-05-26 at 09:45 +1000, Keenan, Greg John (Greg)** CTR **
> wrote:
> print (@lines)[0 .. $numTapes{"$cfg"}];


That will produce a syntax error. You have the print(@lines) function
followed by an anonymous array.



John
--
use Perl;
program
fulfillment
Greg John ** CTR ** Keenan

2006-05-25, 6:58 pm

>Using an AoA:
>
>for my $cfg ( @cfgs ) {
> my $fileIn = "$cfgDir/$cfg->[0]/tapelist";
> open FILEIN, '<', $fileIn or die "Could not open $fileIn: $!";
> print +( reverse <FILEIN> )[ -$cfg->[1] .. -1 ]; }
>
>Using a hash:
>
>for my $cfg ( keys %cfgs ) {
> my $fileIn = "$cfgDir/$cfg/tapelist";
> open FILEIN, '<', $fileIn or die "Could not open $fileIn: $!";
> print +( reverse <FILEIN> )[ -$cfg{$cfg} .. -1 ]; }
>
>
>Also, if the files are large you can get better efficiency using
>the File::ReadBackwards module.



Thanks for the solutions John, works a treat. Files are quite small but
will look into File::ReadBackwards

Regards,
Greg.
kenslaterpa@hotmail.com

2006-05-25, 9:57 pm


Greg John ** CTR ** Keenan wrote:
> Hi,
>
> What is the best way to only work with the first x number of elements in an
> array?
>
> At the moment this script prints the entire contents of @lines for each
> element in @cfgs
>
> I would like to restrict this to the number of elements listed in the hash
> %numTapes for each element in @cfgs
>
> Any suggestions for improving this script much appreciated.
>
> Thanks,
> Greg.
>
>


Greg, Wanted to make a suggestion, although not being familiar with you
problem
and file format, I may be way off base. Is it necessary to hard code
the number
of tapes in the script? Or is there a way to determine (probably via
regular
expression) which are the lines of interest in the data file. If done
in this manner,
a change to the number of tapes would only require a change to the data
file and
not to the script (which could be easily forgotten).
Of course this may not be an option for you.
Ken

John W. Krahn

2006-05-25, 9:57 pm

John W. Krahn wrote:
> Keenan, Greg John (Greg)** CTR ** wrote:
>
> Do you really need an array and a hash? If you need keep the order of @cfgs
> you could use an array of arrays:
>
> my @cfgs = (
> [ Toaster => 6 ],
> [ MFG-UNIX => 5 ],
> [ SYS-UNIX => 5 ],
> [ Amanda-Daily => 1 ],
> );
>
> If you don't really care about the order then just use a hash:
>
> my %cfgs = (
> Toaster => 6,
> MFG-UNIX => 5,
> SYS-UNIX => 5,
> Amanda-Daily => 1,
> );


Small correction: because of the hyphens those barewords need to be quoted.

my @cfgs = (
[ Toaster => 6 ],
[ 'MFG-UNIX' => 5 ],
[ 'SYS-UNIX' => 5 ],
[ 'Amanda-Daily' => 1 ],
);

my %cfgs = (
Toaster => 6,
'MFG-UNIX' => 5,
'SYS-UNIX' => 5,
'Amanda-Daily' => 1,
);


:-)

John
--
use Perl;
program
fulfillment
Greg John ** CTR ** Keenan

2006-05-25, 9:57 pm

>Small correction: because of the hyphens those barewords need to be quoted.
>
>my @cfgs = (
> [ Toaster => 6 ],
> [ 'MFG-UNIX' => 5 ],
> [ 'SYS-UNIX' => 5 ],
> [ 'Amanda-Daily' => 1 ],
> );
>
>my %cfgs = (
> Toaster => 6,
> 'MFG-UNIX' => 5,
> 'SYS-UNIX' => 5,
> 'Amanda-Daily' => 1,
> );



Yes I picked up on that after I tried to run it. Thanks.
Paul Johnson

2006-05-25, 9:57 pm

On Fri, May 26, 2006 at 10:35:41AM +1000, Keenan, Greg John (Greg)** CTR ** wrote:

>
> Thanks for the solutions John, works a treat. Files are quite small but
> will look into File::ReadBackwards


This seems to be doing a bit more work than might be required. How
about this?

print reverse map scalar <FILEIN>, 1 .. $cfg{$cfg};

Then you won't need to worry about how big the files are.

--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com