Sorry, I guess I thought it was more apparent with the code. I'm actually trying to get a lot of different sorted lists. Earlier in the program, I've taken a list of names from a database, and depending on which group a person is in, it puts their email address into an array (team1, team2, team3, etc). But it doesn't sort them. So I want to sort all those separate arrays.
The two commands I noted above in the first set of code will do it if I use them for each team, but I've got about 10 different teams and I know there's got to be an easier way then typing out the code 10 different times.
bburton
06-21-2005, 10:30 AM
It seems to me that it might be easier to sort this data as it's being assigned, earlier on in the code.
Maybe you could post more of the script, specifically the part where these email arrays are loaded up?
gschimek
06-21-2005, 02:08 PM
Here's the entire subroutine that reads the text file containing the list, and puts their email addresses into separate arrays based on the team that they are on.
sub createTeamLists {
#split the text file up into separate values and place them in an array
foreach $email_entry (@raw_data)
{
($first_name,$last_name,$address,$city,$state,$zip ,$phone,$team,$gender,$grad_year,$email,$tec_numbe r,$rector)=split(/\,/,$email_entry);
#read the data and add to separate team lists
#=~ comparison operator matches if the variable simply contains the string. Does not
#need to be an exact match.
#/i option ignores case
if ($team =~ /atl/i)
{
if ($email ne "") {push (@atl_emails, "$email");}
$atl_members++;
}
elsif ($team =~ /ytl/i)
{
if ($email ne "") {push (@ytl_emails, "$email");}
$ytl_members++;
}
elsif ($team =~ /music/i)
{
if ($email ne "") {push (@music_emails, "$email");}
$music_members++;
}
elsif ($team =~ /photo/i)
{
if ($email ne "") {push (@music_emails, "$email");}
$music_members++;
}
elsif ($team =~ /Wheat/i)
{
if ($email ne "") {push (@wheat_emails, "$email");}
$wheat_members++;
}
elsif ($team =~ /support/i)
{
if ($email ne "") {push (@support_emails, "$email");}
$support_members++;
}
elsif ($team =~ /kitchen/i)
{
if ($email ne "") {push (@kitchen_emails, "$email");}
$kitchen_members++;
}
elsif ($team =~ /SD/i)
{
if ($email ne "") {push (@sd_emails, "$email");}
$sd_members++;
}
if ($team != /^[ \t]*$/)
{
if ($email ne "") {push (@team_emails, "$email");}
$team_members++;
}
if ($grad_year =~ /adult/i && $team !~ /atl/i)
{
if ($email ne "") {push (@leadership_emails, "$email");}
$leadership_members++;
}
if ($rector =~ /Y/i)
{
if ($email ne "") {push (@leadership_emails, "$email");}
$leadership_members++;
}
}
i dont think you can include variables in the name of another variable. at the very least i dont think it would be good practice. it's not necessary anyway. here's a lazy solution, certainly not the most efficient method but no worse than creating new arrays from the unsorted emails really
#!/usr/bin/perl
my @team_emails1 = ('poo2@team1.com','poo1@team1.com','poo3@team1.com ');
my @team_emails2 = ('poo5@team2.com','poo6@team2.com','poo4@team2.com ');
my @team_emails3 = ('poo9@team3.com','poo8@team3.com','poo7@team3.com ');
my @array_of_unsorted_emails = (\@team_emails1, \@team_emails2, \@team_emails3);
my %hash_of_sorted_emails;
my $team_number = 1;
#sort emails and store each as an anonymous array in %hash_of_sorted_emails
foreach my $team_emails (@array_of_unsorted_emails) {
$hash_of_sorted_emails{$team_number++} = [sort {$a cmp $b} @$team_emails];
}
#output contents of %hash_of_sorted_emails
for my $team (sort keys %hash_of_sorted_emails) {
print "Emails for Team $team:\n";
for ( @{$hash_of_sorted_emails{$team}} ) {
print "$_\n";
}
}
__DATA__
Emails for Team 1:
poo1@team1.com
poo2@team1.com
poo3@team1.com
Emails for Team 2:
poo4@team2.com
poo5@team2.com
poo6@team2.com
Emails for Team 3:
poo7@team3.com
poo8@team3.com
poo9@team3.com
i thought it was gonna look prettier when i started heh
gschimek
06-22-2005, 04:16 PM
OK, something's just not right. Here's the subroutine I'm working on. I tried your code from above by itself and it works great. When I enter it into my subroutine, it doesn't sort anything.
sub createTeamLists {
#split the text file up into separate values and place them in an array
foreach $email_entry (@raw_data)
{
($first_name,$last_name,$address,$city,$state,$zip ,$phone,$team,$gender,$grad_year,$email,$tec_numbe r,$rector)=split(/\,/,$email_entry);
#read the data and add to separate team lists
#=~ comparison operator matches if the variable simply contains the string. Does not
#need to be an exact match.
#/i option ignores case
if ($team =~ /Kitchen/i)
{
if ($email ne "") {push (@kitchen_emails, "$email");}
$kitchen_members++;
}
elsif ($team =~ /support/i)
{
if ($email ne "") {push (@support_emails, "$email");}
$support_members++;
}
if ($rector =~ /Y/i)
{
if ($email ne "") {push (@leadership_emails, "$email");}
$leadership_members++;
}
}
my @array_of_unsorted_emails = (\@leadership_emails, \@support_emails, \@kitchen_emails);
my %hash_of_sorted_emails;
my $team_number = 1;
#sort emails and store each as an anonymous array in %hash_of_sorted_emails
foreach my $team_emails (@array_of_unsorted_emails) {
$hash_of_sorted_emails{$team_number++} = [sort {$a cmp $b} @$team_emails];
}
}
If I add these lines immediately before the last curly bracket, it sorts the @support_emails array just fine.
if ( $team =~ /atl/i ) {
if ($email ne "") {
# also, you can just push $email, no need to stringify it ( "$email" )
push @{ $emails{ 'atl' } }, $email;
}
$atl_members++;
}
elsif ($team =~ /ytl/i)
{
if ($email ne "") {
push @{ $emails{ 'ytl' } }, $email;
}
$ytl_members++;
}
...
Here's the code. There's a lot of time/date checking because it's time sensitive data that's displayed. You can ignore a lot of the subroutines.
I'll post the results next.
#!/usr/local/bin/perl
use CGI qw(:standard);
use Fcntl ':flock';
use CGI::Carp qw(fatalsToBrowser);
#Takes team list consisting of first name, last name, team, and email address in that order
#and creates lists of email addresses in separate windows by team.
#data file must be a comma separated value file called "teamdata.dat"
$data_file="teamdatatest.dat";
open(DAT, $data_file) || die("Could not open file!");
@raw_data=<DAT>;
close(DAT);
open(WEEKEND_DAT, "../weekends/weekends.dat") || die("Could not open file!");
@weekend_data=<WEEKEND_DAT>;
close(WEEKEND_DAT);
#Uses localtime function to get the current time and date
&GetCurrentDate;
#Gets the date of the next weekend
&GetWeekendDate;
#variables to be set for testing purposes
#$candidate_arrival_date='4/25/05';
#$RealMonth=5;
#Changes date from mm/dd/yyyy format to 3 separate variable for month, date, and year
&ParseWeekendDate;
#Changes month notation from text to number. ex. Apr becomes 4
&Change_Current_Month_To_Number;
#Creates a variable for when to change the display and not show the most recently completed weekend
$CutOffDate=$CADate+2;
if ($weekend_month_number<=$RealMonth && $Day>$CutOffDate && $tec_number>=$weekend) {
print "Current team list is not available until closer to the next TEC weekend. Please check back later.";
}
else {
&printResults;
}
sub createTeamLists {
#split the text file up into separate values and place them in an array
foreach $email_entry (@raw_data)
{
($first_name,$last_name,$address,$city,$state,$zip ,$phone,$team,$gender,$grad_year,$email,$tec_numbe r,$rector)=split(/\,/,$email_entry);
#read the data and add to separate team lists
#=~ comparison operator matches if the variable simply contains the string. Does not
#need to be an exact match.
#/i option ignores case
if ($team =~ /atl/i)
{
#open atllist, '>> atllist.dat';
#print atllist "$email\n";
#close atllist;
if ($email ne "") {push (@atl_emails, "$email");}
$atl_members++;
}
if ($team != /^[ \t]*$/)
{
#open entireteam, '>> entireteam.dat';
#print entireteam "$email\n";
#close entireteam;
if ($email ne "") {push (@team_emails, "$email");}
$team_members++;
}
if ($grad_year =~ /adult/i && $team !~ /atl/i)
{
#open leaderlist, '>> leaderlist.dat';
#print leaderlist "$email\n";
#close leaderlist;
if ($email ne "") {push (@leadership_emails, "$email");}
$leadership_members++;
}
if ($rector =~ /Y/i)
{
#open leaderlist, '>> leaderlist.dat';
#print leaderlist "$email\n";
#close leaderlist;
if ($email ne "") {push (@leadership_emails, "$email");}
$leadership_members++;
}
}
my @array_of_unsorted_emails = (\@leadership_emails, \@support_emails, \@kitchen_emails);
my %hash_of_sorted_emails;
my $team_number = 1;
#sort emails and store each as an anonymous array in %hash_of_sorted_emails
foreach my $team_emails (@array_of_unsorted_emails) {
$hash_of_sorted_emails{$team_number++} = [sort {$a cmp $b} @$team_emails];
}
print "<table width=700><tr><td align=center><br><font size=+2 font face=arial><b>TEC $tec_number Team Member Email List By Team</b></font></td></tr></table>";
sub GetWeekendDate {
for $weekend_info (@weekend_data)
{
chop($weekend_info);
($weekend,$weekend_month,$weekend_start_date,$week end_end_date,$weekend_year,$church,$church_website ,$address,$address_url,$city,$state,$zip,$phone,$t eam_arrival_date,$candidate_arrival_date,$departur e_date,$leadership_date,$meeting_1,$meeting_2,$mee ting_3,$reunion_date,$application_deadline)=split(/\|/,$weekend_info);
return (1);
}
}
sub ParseWeekendDate {
($CAMonth, $CADate, $CAYear)=split(/\//,$candidate_arrival_date);
}
gschimek
06-22-2005, 07:47 PM
I've tested 2 ways. Via command line with perl emaillistbak.pl, and also by posting it to my site. It displays fine in both places, except for not sorting.
I've used fake email addresses for the results below.
i think the problem is in the output routine, the sorted emails are gonna be stored in %hash_of _sort_emails, but focusing on your code to print out the support emails you try to access @support_emails, which should contain the original unsorted emails. the sorted emails are gonna be stored in an anonymous array inside of %hash_of_sorted_emails
arrays of support, leadership, etc emails are keyed numerical in the %hash_of_sorted_emails structure. i havent checked but it looks like the sorted copy of @support_emails will get keyed to $hash_of_sorted_emails{1}, which you dereference as a list to obtain the sorted emails. you might wanna tweak the sort routine to key the arrays as "support", "leadership", etc for clarity later.
gschimek
06-22-2005, 08:58 PM
I made the change you noted and now it doesn't output any addresses--sorted or unsorted.
Would it help if I removed all the references to the files that get opened so that you could test it?
flukshun
06-22-2005, 09:46 PM
i really dont know what's goin on on your end there. one mistake in my last reply was that the hash key for the support emails would be '2', not '1'. i forgot i started at 1, but still...it should've printed at least the leadership emails or whatever. cutting out the other stuff this is the test script i put together:
my @array_of_unsorted_emails = (\@leadership_emails, \@support_emails, \@kitchen_emails);
my %hash_of_sorted_emails;
my $team_number = 1;
#sort emails and store each as an anonymous array in %hash_of_sorted_emails
foreach my $team_emails (@array_of_unsorted_emails) {
$hash_of_sorted_emails{$team_number++} = [sort {$a cmp $b} @$team_emails];
}
here's the output:
fluxion@purity:~/scripts$ ./email.pl
me3@support.com<br>
me4@support.com<br>
me9@support.com<br>
fluxion@purity:~/scripts$
so go ahead and change the hash key on the output routine to '2' and give it another shot. otherwise i dont see why it wouldn't work on my end, assuming @support_emails is just a list of emails, since i took the code straight out of your latest script and simply loaded the arrays manually and changed the hash key on the output routine.
gschimek
06-22-2005, 11:01 PM
I figured it out. In the code you suggested, you were using (I forget the actualy term) non-global arrays and hashes with "my @array_of_unsorted_emails" and "my %hash_of_sorted_emails"
I was calling them from a different subroutine, and since they weren't global, I think they were empty as far as the other subroutine was concerned.
I removed the "my's" and it's working fine.
Thanks for the help.
justlinux.com
Copyright Internet.com Inc. All Rights Reserved.