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
|
|
|
|
|