OK, so I have an array item which could have as many as 600 elements separated by a comma and which, I read in from (config) flat file.
surely there is a more efficient method than this:
my @array = 1,2,3,4,5,6.....500;
my ($firstElement, $secondElement, $FiveHundredthElement) = split /\,/ , @array, 500;
The array will not always have 500 elements, as mostly it will have about 50 +/- 25.
Maybe I should reconfure the inputter to the Config file, so that each room number is in a separate array?
Perhaps there's a default variable which I could use in a foreach loop?
Bazz
FishMonger
02-19-2006, 07:02 PM
surely there is a more efficient method than this:There sure is, and I'm sure you know what my answer will be. :) :) A mysql database. :) :)
Can you give me more info on the array you're splitting and the hash you want to build from that split?
Assuming each array element is a comma seperated list, you could fill a temp array of the split fields and then a map command on that 2nd array. I'll wait until you post more details before I work up any code.
Each array is separated by a comma but I thought it would be very verbose to split the array on perhaps 500 $variables.
The array would be comprised like this:
01,02,04,05,06 and in other cases
101,102, thru to 199,201,202,203 thru to 299 and so on.
The file reading in the data is as follows.
### open config file to readIn data for process #####
my $dat_file ="/domains/574/2317/html/cgi-bin/$clientsReservationsDir/Config"; # location of config file
open DAT, "< $dat_file" || die "couldnt open file\n";
while ( my $Line = <DAT> ) {
last if ( index($Line, ':') == -1 );
chomp $Line;
my ( $Keyword, $Value ) = split /:/, $Line, 2; #splits the line at the first : ignoring any others
if ($Keyword eq "AccommName") {
$AccommName = $Value;
} elsif ($Keyword eq "NumberOfDoubleRooms") {
$NumberOfDoubleRooms = $Value;
} elsif ($Keyword eq "DoubleRoomNumbers"){
@DoubleRoomNumbers = $Value;
} elsif ($Keyword eq "NumberOfSingleRooms") {
$NumberOfSingleRooms = $Value;
} elsif ($Keyword eq "SingleRoomNumbers") {
@SingleRoomNumbers = $Value;
} elsif ($Keyword eq "NumberOfFamilyRooms") {
$NumberOfFamilyRooms = $Value;
} elsif ($Keyword eq "FamilyRoomNumbers") {
@FamilyRoomNumbers = $Value;
} elsif ($Keyword eq "NumberOfTwinRooms") {
$NumberOfTwinRooms = $Value;
} elsif ($Keyword eq "TwinRoomNumbers") {
@TwinRoomNumbers = $Value;
} elsif ($Keyword eq "DoubleRoomRackRate") {
$DoubleRoomRackRate = $Value;
} elsif ($Keyword eq "SingleRoomRackRate") {
$SingleRoomRackRate = $Value;
} elsif ($Keyword eq "TwinRoomRackRate") {
$TwinRoomRackRate = $Value;
} elsif ($Keyword eq "FamilyRoomRackRate") {
$FamilyRoomRackRate = $Value;
} else {
warn "unknown field";
}
}
close DAT;
I am trying to run a loop which will result in the creation of a filename like this
Double_01_2008-01-04
RoomType_RoomNumber_Date(yyyy-mm-dd).
This part of the code is meant to build the RoomType and RoomNumber.
Ultimately the whole script, will create a Dir and in it, an empty file named for each roomType_RoomNumber_date in that year.
Bazz
Separately I have the code for creating the date though it only does the year and dates so far.
FishMonger
02-19-2006, 07:57 PM
I've got 1 or 2 ideas, but I'll need to do some testing before I make a recommendation.
I say this with all due respect, you can not expect to create an application as large and complex as you're doing without the use of a relational database and or proper config files.
You need to take a serious look at these config modules.
http://search.cpan.org/~tlinden/Config-General-2.31/General.pm
http://search.cpan.org/~nikratio/Config-Generic-0.01/lib/Config/Generic.pm
http://search.cpan.org/~kirsle/Config-INI-Simple-0.01/lib/Config/INI/Simple.pm
http://search.cpan.org/~mgraham/Config-Context-0.10/lib/Config/Context/XMLSimple.pm
FishMonger
02-19-2006, 08:07 PM
My first recommendation, which is just for cleanup purposes, is to drop all of those elsif blocks.
my %accomidations;
while ( chomp (my $Line = <DAT>) ) {
last if ( index($Line, ':') == -1 );
my ( $Keyword, $Value ) = split /:/, $Line, 2; #splits the line at the first : ignoring any others
$accomidations{$keyword} = $value;
}
FishMonger
02-19-2006, 08:42 PM
Here's an abbreviated version that does what you need.
#!/usr/bin/perl -w
$date = '2008-01-04';
%accomidations = ('SingleRoomNumbers' => '1,2,3,4,5',
'DoubleRoomNumbers' => '6,7,8,9,10',
);
foreach ( qw(SingleRoomNumbers DoubleRoomNumbers) ){
$type = $1 if $_ =~ /^(.*?)RoomNumbers/;
@rooms = split ',', $accomidations{$_};
foreach $room (@rooms) {
print join ('_', ($type, $room, $date)), $/;
}
}
Outputs:
Single_1_2008-01-04
Single_2_2008-01-04
Single_3_2008-01-04
Single_4_2008-01-04
Single_5_2008-01-04
Double_6_2008-01-04
Double_7_2008-01-04
Double_8_2008-01-04
Double_9_2008-01-04
Double_10_2008-01-04
@ FishMonger, that works great now. Having had to build a Hash to create the date, I have learned some more. :) Quite chuffed, really.
@everyone,
All done now, but for making the script work out the number of days in each month. Presently it 'thinks' there are 31 in each month.
I would think that making a separate hash for each month type, (30 31 28/29 days), would be excessive so I wonder whether I should use code to exit the loop after a specified number of times (set conditionally) or, should I make a hash like this,
my %months (
January => 01,
January => 02,
January => 03 etc
January => 31,
February => 01
February => 02
February => 03
February => 04
February => 28
FebruaryLeap => 29
or should I use an array for the number of dates in a conditional
if ($month eq "April" || $month eq "September" || $month eq "June" || $month eq "November"){
my @potentialDatesOfMonth =('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20 ','21','22','23','24','25','26','27','28','29','30');
print "pDoM = @potentialDatesOfMonth<br />";
}
if ( $yearDivided =~ m/\./ && $month eq 'February' ) {
my @potentialDatesOfMonth =('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20 ','21','22','23','24','25','26','27','28');
print "pDoM = @potentialDatesOfMonth<br />";
} elsif ( $month eq 'February' ){
print "$nextYear is a leap Year<br />";
my @potentialDatesOfMonth =('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20 ','21','22','23','24','25','26','27','28','29');
print "pDoM = @potentialDatesOfMonth<br />";
}
if ( $month eq "January" || $month eq "March" || $month eq 'May' || $month eq 'July' || $month eq ' August' || $month eq 'October' || $month eq 'December' ) {
my @potentialDatesOfMonth =('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20 ','21','22','23','24','25','26','27','28','29','30','31');
print "pDoM = @potentialDatesOfMonth<br />";
}
This is the code from the appropriate point in the script:
foreach my $Month (sort values %months) {
print "month1 =$Month<br />\n"; #successful
foreach $Date (sort values %dates) {
$YMD = join ("-", ($nextYear, $Month, $Date));
#print "$YMD\n"; # successful
foreach ( qw( SingleRoomNumbers DoubleRoomNumbers TwinRoomNumbers FamilyRoomNumbers ) ){
$type = $1 if $_ =~ /^(.*?)RoomNumbers/;
@rooms = split ',', $accommodations{$_};
foreach $room (@rooms) {
my $filenames = join ('_', ($type, $room, $YMD)), $/;
print "fileNames = $filenames<br />\n";
}
}
}
}
Bazz
FishMonger
02-21-2006, 05:24 PM
Is there some reason you don't want to use one of the date modules?
Date::Calc http://search.cpan.org/~stbey/Date-Calc-5.4/Calc.pod
Date::Manip http://search.cpan.org/~sbeck/DateManip-5.44/Manip.pod
If you want to do it manually, I'd probably use a hash that gives the number of days for each month.
my %months = (
January => 31,
February => 28,
March => 31,
etc,
);
Then you can loop through each month of the hash using its value as the exit point for the next loop.
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.