treyjeff
asked on
Sorting an array?
I'd like to do the following:
I have guys make over/under picks and it saves the selections to a file. I want to have the selections checked against another "result file" if you will. Then for each guys I want it to generate standings. How would one propose I do that and have them listed from top to bottom. I can award say 5 points for each right answer and even keep the score in the owner file. I want to keep it basic as well so that I, a bieginner can understand it.
I have guys make over/under picks and it saves the selections to a file. I want to have the selections checked against another "result file" if you will. Then for each guys I want it to generate standings. How would one propose I do that and have them listed from top to bottom. I can award say 5 points for each right answer and even keep the score in the owner file. I want to keep it basic as well so that I, a bieginner can understand it.
perldoc -f sort
ASKER
Ozo, why do you keep posting that stuff? Besides, where would I enter that? I don't have access to a prompt to test this stuff out on.
What do you have access to? How were you expecting to develop your program?
But if you don't have access to perl or perldoc, you can still find documentation here:
http://www.perl.com/pub/doc/manual/html/pod/perlfunc/sort.html
But if you don't have access to perl or perldoc, you can still find documentation here:
http://www.perl.com/pub/doc/manual/html/pod/perlfunc/sort.html
Assumming your array is @my_array
you can have it sorted by:
@my_sorted_array = sort @my_array;
is that what you had in mind?
you can have it sorted by:
@my_sorted_array = sort @my_array;
is that what you had in mind?
can u be more clear in what exactly u want .u say u want to sort an array ?
but what does ur array have in it?
if u just wanna sort then
Sshlomoy has given u the answer.
but what does ur array have in it?
if u just wanna sort then
Sshlomoy has given u the answer.
ASKER
I have access to FTP to upload my scripts, that's it. I write my scripts in notepad and if I run into trouble I debug with Visual Perl Edit. If I have an array that breaks out to the following:
team, owner, ownersemail, score, icqnumber
I want to sort the array on the score element. It's actually a file I read into an array so it may look like this:
Toronto|Jeff|jeff@hyrum.ne t|98|57180 3
Baltimore|Ozo|email@email. com|12|123 456
Detroit|Schlomoy|email@ema il.com|78| 34567
Calgary|Kishore|email@emai l.com|67|9 8765
I want it sorted by the score element so I can print it out into an html file.
team, owner, ownersemail, score, icqnumber
I want to sort the array on the score element. It's actually a file I read into an array so it may look like this:
Toronto|Jeff|jeff@hyrum.ne
Baltimore|Ozo|email@email.
Detroit|Schlomoy|email@ema
Calgary|Kishore|email@emai
I want it sorted by the score element so I can print it out into an html file.
here is a very flexible sorting routine.
you can customize it to sort ANY column that you want either numerically of alphabetically.
by adding some more code you can reverse sort too!!
===score
Toronto|Jeff|jeff@hyrum.ne t|98|57180 3
Baltimore|Ozo|email@email. com|12|123 456
Detroit|Schlomoy|email@ema il.com|78| 34567
Calgary|Kishore|email@emai l.com|67|9 8765
========score.pl
#!/usr/local/bin/perl
$WebFileName = "/home/webuser/manesh/tmp/ score";
open(MYFILE,"$WebFileName" ) || die $!;
@recs=<MYFILE>;
close(MYFILE);
## Column num (starting from 1), type of sort
## n = numeric, a = alphabetic & Array to sort
@new=&my_sort(4,"n",@recs) ;
## Here are some more samples that you could try
##@new=&my_sort(1,"a",@rec s);
##@new=&my_sort(2,"a",@rec s);
## Print out the results
foreach(@new){
print $_;
}
sub my_sort{
($col,$type,@arr)=@_;
$col--;
$type="a" if $type!~ /^n$/i; ## Default Alphabetic sort
foreach(@arr){
@tmp=split(/\|/,$_);
return 0 if ($col<0 || $col>(scalar @arr)); ## Invalid col no.
$new_arr=join('|',$tmp[$co l],$_);
push(@new_arr,$new_arr);
}
if ($type=~ /^n$/i){ ## Numeric Sort
@new_arr=sort bynum @new_arr
}else{
@new_arr=sort byalp @new_arr
}
@arr=""; ## Re initialize the array
foreach(@new_arr){
@tmp=split(/\|/,$_);
shift(@tmp); ## Remove the 1st column
$new_arr=join('|',@tmp);
push(@arr,$new_arr);
}
return @arr;
}
sub bynum{ $a <=> $b;}
sub byalp{ $a cmp $b;}
you can customize it to sort ANY column that you want either numerically of alphabetically.
by adding some more code you can reverse sort too!!
===score
Toronto|Jeff|jeff@hyrum.ne
Baltimore|Ozo|email@email.
Detroit|Schlomoy|email@ema
Calgary|Kishore|email@emai
========score.pl
#!/usr/local/bin/perl
$WebFileName = "/home/webuser/manesh/tmp/
open(MYFILE,"$WebFileName"
@recs=<MYFILE>;
close(MYFILE);
## Column num (starting from 1), type of sort
## n = numeric, a = alphabetic & Array to sort
@new=&my_sort(4,"n",@recs)
## Here are some more samples that you could try
##@new=&my_sort(1,"a",@rec
##@new=&my_sort(2,"a",@rec
## Print out the results
foreach(@new){
print $_;
}
sub my_sort{
($col,$type,@arr)=@_;
$col--;
$type="a" if $type!~ /^n$/i; ## Default Alphabetic sort
foreach(@arr){
@tmp=split(/\|/,$_);
return 0 if ($col<0 || $col>(scalar @arr)); ## Invalid col no.
$new_arr=join('|',$tmp[$co
push(@new_arr,$new_arr);
}
if ($type=~ /^n$/i){ ## Numeric Sort
@new_arr=sort bynum @new_arr
}else{
@new_arr=sort byalp @new_arr
}
@arr=""; ## Re initialize the array
foreach(@new_arr){
@tmp=split(/\|/,$_);
shift(@tmp); ## Remove the 1st column
$new_arr=join('|',@tmp);
push(@arr,$new_arr);
}
return @arr;
}
sub bynum{ $a <=> $b;}
sub byalp{ $a cmp $b;}
open (F, "input.txt");
while (<F>) {
$Line = $_;
@Field = split /\|/, $Line;
# Build a hash, using the score as the
# key and the whole line as the value
$Hash{$Field[3]} = $Line;
}
# Print the contents of the hash in score order
foreach (sort keys %Hash) {
print $Hash{$_};
}
while (<F>) {
$Line = $_;
@Field = split /\|/, $Line;
# Build a hash, using the score as the
# key and the whole line as the value
$Hash{$Field[3]} = $Line;
}
# Print the contents of the hash in score order
foreach (sort keys %Hash) {
print $Hash{$_};
}
If you want them sorted from highest to lowest, then replace the 'foreach' line with
foreach (sort {$b <=> $a} keys %Hash) {
foreach (sort {$b <=> $a} keys %Hash) {
See also Sort::Fields
what's wrond using UNIX's sort?
cat my_file | sort -k column
example:
Consider the file sortMe:
bbb aaa zzz eee
ccc ddd eee fff
aaa fff ggg xxx
ddd vvv fff ggg
aaa bbb www ddd
$> cat sortMe | sort -k 1
aaa bbb www ddd
aaa fff ggg xxx
bbb aaa zzz eee
ccc ddd eee fff
ddd vvv fff ggg
$> cat sortMe | sort -k 2
bbb aaa zzz eee
aaa bbb www ddd
ccc ddd eee fff
aaa fff ggg xxx
ddd vvv fff ggg
from PERL you can call this using the command substitution:
`cat sortMe | sort -k 3 > soreted`
cat my_file | sort -k column
example:
Consider the file sortMe:
bbb aaa zzz eee
ccc ddd eee fff
aaa fff ggg xxx
ddd vvv fff ggg
aaa bbb www ddd
$> cat sortMe | sort -k 1
aaa bbb www ddd
aaa fff ggg xxx
bbb aaa zzz eee
ccc ddd eee fff
ddd vvv fff ggg
$> cat sortMe | sort -k 2
bbb aaa zzz eee
aaa bbb www ddd
ccc ddd eee fff
aaa fff ggg xxx
ddd vvv fff ggg
from PERL you can call this using the command substitution:
`cat sortMe | sort -k 3 > soreted`
Solving it in Perl:
read in the file lines into a hash, where the key is the data in the column you want to sort by and the data is all the line.
After reading in the file, sort your hash using sort keys.
read in the file lines into a hash, where the key is the data in the column you want to sort by and the data is all the line.
After reading in the file, sort your hash using sort keys.
Hi treyjeff ,
did you get a chance to evaluate the various solutions proposed by the experts??
which one worked for you?? do let us know....
Thanks
did you get a chance to evaluate the various solutions proposed by the experts??
which one worked for you?? do let us know....
Thanks
ASKER
Sorry guys, will try it sometime Thursday or Friday unless I can sneak some time here at work :)
ASKER
Just an update, will be testing tomorrow.
ASKER
PC USer I have tried yours as it appears the least amount of code. My code for what I'm doing is already huge. Here is the code I have to see the standings, all it does is display the last record:
#!/usr/bin/perl
require "cgi-lib.pl";
#set content type
print &PrintHeader;
#initialize variables
$optionfile = "/usr/local/www/htdocs/hyr um/polldat a/firstgam e.txt";
open (FILE, "$optionfile");
while (<FILE>) {
$Line = $_;
@Field = split /\|/, $Line;
# Build a hash, using the score as the
# key and the whole line as the value
$Hash{$Field[23]} = $Line;
}
# Print the contents of the hash in score order
foreach (sort {$b <=> $a} keys %Hash) {
print $Hash{$_};
print <BR>
}
###End of program
#!/usr/bin/perl
require "cgi-lib.pl";
#set content type
print &PrintHeader;
#initialize variables
$optionfile = "/usr/local/www/htdocs/hyr
open (FILE, "$optionfile");
while (<FILE>) {
$Line = $_;
@Field = split /\|/, $Line;
# Build a hash, using the score as the
# key and the whole line as the value
$Hash{$Field[23]} = $Line;
}
# Print the contents of the hash in score order
foreach (sort {$b <=> $a} keys %Hash) {
print $Hash{$_};
print <BR>
}
###End of program
Your code looks good.
Glad I could help.
Glad I could help.
ASKER
Adjusted points to 50
ASKER
I'm not ready to accept as it doesn't yet do what I was looking for. I want all the records to display :) For some reason it only prints one record and it happens to be the last one in the file. While it prints every field and that is ok, if I could only print a few fields like 5,6,23 that would be even better.
treyjeff,
your should probably try the code i had provided earlier. Like i said, its a very flexible sorting routine. You can customize it to sort ANY column that you want either numerically of alphabetically.
By adding some more code you can reverse sort too!!
your should probably try the code i had provided earlier. Like i said, its a very flexible sorting routine. You can customize it to sort ANY column that you want either numerically of alphabetically.
By adding some more code you can reverse sort too!!
ASKER
maneshr, there is just so much code to it and I have no idea what half of it means.
yes, you are right. due to this somewhat large code you have the flexibility of sorting on any column. Also i have put in validation checks so that you can just take the code as-is and integrate it with your code, without having to do any more checking.
However the heart of the code is this snippet, that takes the array that you passed and sorts it.
foreach(@arr){
@tmp=split(/\|/,$_);
return 0 if ($col<0 || $col>(scalar @arr)); ## Invalid col no.
$new_arr=join('|',$tmp[$co l],$_);
push(@new_arr,$new_arr);
}
if you want me to comment every line of the code and also explain the logic, pl let me know.
However the heart of the code is this snippet, that takes the array that you passed and sorts it.
foreach(@arr){
@tmp=split(/\|/,$_);
return 0 if ($col<0 || $col>(scalar @arr)); ## Invalid col no.
$new_arr=join('|',$tmp[$co
push(@new_arr,$new_arr);
}
if you want me to comment every line of the code and also explain the logic, pl let me know.
ASKER
Sure if you don't mind doing that, that would be good. You can even email me with all the comments if that's easier. jeff@hyrum.net
here is the commented code. i have put in examples whereever possible. in case you need more commenting/examples, pl let me know
==================score.pl
#!/usr/local/bin/perl
## Full Path to the File that needs to be sorted
$WebFileName = "/home/webuser/manesh/tmp/ score";
## Open the file for reading. If open is unsuccessfull...
## ... show the reason and exit the program
open(MYFILE,"$WebFileName" ) || die $!;
## "Slurp" the ENTIRE file, so that every line in the ...
## ... file is stored as an element in the array
@recs=<MYFILE>;
close(MYFILE); ## Close the file
## Column num (starting from 1), type of sort
## n = numeric, a = alphabetic & Array to sort
@new=&my_sort(2,"a",@recs) ;
## Print out the array after the sorting has been done.
foreach(@new){
print $_;
}
## Subroutine that does the actual sort.
## Accepts 3 params viz. the column number to sort
## Column no starts with 1. The type of sort numeric or alphabetic
## The array that needs to be sorted.
sub my_sort{
($col,$type,@arr)=@_;
## Deduct 1 from the column.
## We do this because in PERL array subscript starts with 0.
## So in human terms when we say column 2 it means column 1 in PERL terms!!
$col--;
## To take care of conditions where user has passed anything other
## ... than a "n" or "N". Eg. if the user has said &mt_sort(3,"z",@array), we ignore the z and perform an alphabetic sort ("a").
$type="a" if $type!~ /^n$/i; ## Default Alphabetic sort
## Process every element of the array
foreach(@arr){
## Split every line using | as the delimiter.
@tmp=split(/\|/,$_);
## After we split we know how many columns are ..
## ... present in every record. Now we have to ...
## ... take care of situations where the user might want ..
## ... to sort on non-existant or invalid columns.
## Eg. Each record has 6 columns and the user has passed 7 or 8
## ... or -1 etc...
return 0 if ($col<0 || $col>(scalar @arr)); ## Invalid col no.
## This is important. We take the column that the user wants ...
## ... to sort on and pre-pend it to the record itself.
## Let's say the record is ...
# Toronto|Jeff|jeff@hyrum.ne t|98|57180 3
## ...& the user wants to sort on the 2nd column (PERL subscript 1).
$new_arr=join('|',$tmp[$co l],$_);
## After the above the record will be...
# Jeff|Toronto|Jeff|jeff@hyr um.net|98| 571803
## Store this new record in an array
push(@new_arr,$new_arr);
}
## Determine the type of sort
if ($type=~ /^n$/i){ ## Numeric Sort
## Sort the array by number using the bynum subroutine
@new_arr=sort bynum @new_arr
}else{ ## Alphabetic sort
## Sort the array by alphabets using the byalp subroutine
@new_arr=sort byalp @new_arr
}
@arr=""; ## Re initialize the array
## Remember our sort is done, but we still have that...
## ...extra column at the beggining that we must remove!!
foreach(@new_arr){
## Split every line using | as the delimiter.
@tmp=split(/\|/,$_);
shift(@tmp); ## Remove that 1st column
## So before the shift if we had....
# Jeff|Toronto|Jeff|jeff@hyr um.net|98| 571803
## After th shift we will have...
# Toronto|Jeff|jeff@hyrum.ne t|98|57180 3
## Join the array as one record...
$new_arr=join('|',@tmp);
## ...& store it in another array.
push(@arr,$new_arr);
}
## Return the final array (in sorted order)
return @arr;
}
sub bynum{ $a <=> $b;}
sub byalp{ $a cmp $b;}
==================score.pl
#!/usr/local/bin/perl
## Full Path to the File that needs to be sorted
$WebFileName = "/home/webuser/manesh/tmp/
## Open the file for reading. If open is unsuccessfull...
## ... show the reason and exit the program
open(MYFILE,"$WebFileName"
## "Slurp" the ENTIRE file, so that every line in the ...
## ... file is stored as an element in the array
@recs=<MYFILE>;
close(MYFILE); ## Close the file
## Column num (starting from 1), type of sort
## n = numeric, a = alphabetic & Array to sort
@new=&my_sort(2,"a",@recs)
## Print out the array after the sorting has been done.
foreach(@new){
print $_;
}
## Subroutine that does the actual sort.
## Accepts 3 params viz. the column number to sort
## Column no starts with 1. The type of sort numeric or alphabetic
## The array that needs to be sorted.
sub my_sort{
($col,$type,@arr)=@_;
## Deduct 1 from the column.
## We do this because in PERL array subscript starts with 0.
## So in human terms when we say column 2 it means column 1 in PERL terms!!
$col--;
## To take care of conditions where user has passed anything other
## ... than a "n" or "N". Eg. if the user has said &mt_sort(3,"z",@array), we ignore the z and perform an alphabetic sort ("a").
$type="a" if $type!~ /^n$/i; ## Default Alphabetic sort
## Process every element of the array
foreach(@arr){
## Split every line using | as the delimiter.
@tmp=split(/\|/,$_);
## After we split we know how many columns are ..
## ... present in every record. Now we have to ...
## ... take care of situations where the user might want ..
## ... to sort on non-existant or invalid columns.
## Eg. Each record has 6 columns and the user has passed 7 or 8
## ... or -1 etc...
return 0 if ($col<0 || $col>(scalar @arr)); ## Invalid col no.
## This is important. We take the column that the user wants ...
## ... to sort on and pre-pend it to the record itself.
## Let's say the record is ...
# Toronto|Jeff|jeff@hyrum.ne
## ...& the user wants to sort on the 2nd column (PERL subscript 1).
$new_arr=join('|',$tmp[$co
## After the above the record will be...
# Jeff|Toronto|Jeff|jeff@hyr
## Store this new record in an array
push(@new_arr,$new_arr);
}
## Determine the type of sort
if ($type=~ /^n$/i){ ## Numeric Sort
## Sort the array by number using the bynum subroutine
@new_arr=sort bynum @new_arr
}else{ ## Alphabetic sort
## Sort the array by alphabets using the byalp subroutine
@new_arr=sort byalp @new_arr
}
@arr=""; ## Re initialize the array
## Remember our sort is done, but we still have that...
## ...extra column at the beggining that we must remove!!
foreach(@new_arr){
## Split every line using | as the delimiter.
@tmp=split(/\|/,$_);
shift(@tmp); ## Remove that 1st column
## So before the shift if we had....
# Jeff|Toronto|Jeff|jeff@hyr
## After th shift we will have...
# Toronto|Jeff|jeff@hyrum.ne
## Join the array as one record...
$new_arr=join('|',@tmp);
## ...& store it in another array.
push(@arr,$new_arr);
}
## Return the final array (in sorted order)
return @arr;
}
sub bynum{ $a <=> $b;}
sub byalp{ $a cmp $b;}
There is a typo in the code above.
Please change ....
return 0 if ($col<0 || $col>(scalar @arr); ## Invalid col no.
to ..............
return 0 if ($col<0 || $col>(scalar @tmp)); ## Invalid col no.
Please change ....
return 0 if ($col<0 || $col>(scalar @arr); ## Invalid col no.
to ..............
return 0 if ($col<0 || $col>(scalar @tmp)); ## Invalid col no.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Excellent way to srt. Quite hard to know what was going on so I appreciate the extra effort you put in.
Wow, things have developed since I left my computer!
The trouble with my sort was that it did not allow for duplicates.
Here is the corected code:
open (FILE, "$optionfile") or die $!;
@Sorted = sort byScore <FILE>;
print @Sorted;
sub byScore {
@FieldA = split /\|/, $a;
@FieldB = split /\|/, $b;
$FieldB[3] <=> $FieldA[3];
}
The trouble with my sort was that it did not allow for duplicates.
Here is the corected code:
open (FILE, "$optionfile") or die $!;
@Sorted = sort byScore <FILE>;
print @Sorted;
sub byScore {
@FieldA = split /\|/, $a;
@FieldB = split /\|/, $b;
$FieldB[3] <=> $FieldA[3];
}
With you data, you must change [3] to [23]
With you data, you must change [3] to [23]
ASKER
PC User, I will check it out as well and perhaps give you some points as well in another question, especially if you can get it to show how to print like I'm aking below.
Manesh, how can I change
foreach(2,24){
print $which_cols[$_],"\t";
}
print "\n";
}
So that I can add some HTML around it? For example a table and print one (2) in one column and (24) in the one next to it?
Manesh, how can I change
foreach(2,24){
print $which_cols[$_],"\t";
}
print "\n";
}
So that I can add some HTML around it? For example a table and print one (2) in one column and (24) in the one next to it?
print "Content-type: text/html\n\n";
print "<TABLE BORDER=1>\n";
foreach(@arr){
foreach(2,24){
print "<TD>",$which_cols[$_],"</
}
print "<TR>\n";
}
print "</TABLE>\n";
This will print your results in an HTML table.
In my code the contents of the table is printed like this:
foreach $Line (@Sorted) {
@Fields = split /\|/, $Line;
printf("<TD>%s<\/TD><TD>%s <\/TD><TR> \n", $Fields[2], $Fields[24]);
}
foreach $Line (@Sorted) {
@Fields = split /\|/, $Line;
printf("<TD>%s<\/TD><TD>%s
}
ASKER
Manesh, I get a 500 server error with yours.
check the permission of the .pl file and see if you can execute the same from the command prompt.
i tried the above and it works fine on my system.
i tried the above and it works fine on my system.
ASKER
Sorry, was late. I actualy did get it to run lastnight. Can be seen at www.hyrum.net/cgi-bin/cgiwrap/hyrum/standings.pl
I'm just going to see how to add some nice formatting around it and everything :) Also, still going to try PCUsers
I'm just going to see how to add some nice formatting around it and everything :) Also, still going to try PCUsers
what solved the "500 server error"??
ASKER
It was that I had the table tag inside the first for loop instead of outside it.
ahhh!!!