Secondary sorting keys | Member | | Join Date: Jul 2007
Posts: 40
| |
my flat field DB fields are: [Name,Code,Category]
I have them sorted by field [3] (category=TeachersActivity or ChildrensBooks) so they are grouped together as Children's Books then Teacher Activities -
open(BASE, $dbk) || do {&no_open;};
-
my @sorted = <BASE>;
-
close(BASE);
-
-
foreach my $line (sort cat @sorted) {
-
my @show = split ',', $line;
-
-
-
....
-
-
sub cat {
-
@x = split ',', $a;
-
@y = split ',', $b;
-
return ($x[2] cmp $y[2]);
-
}
the result is: -
Children and Their World - Children's Books
-
Nature - Children's Books
-
Animals - Children's Books
-
Families - Children's Books
-
Learning About Myself - Children's Books
-
Thinking Skills - Children's Books
-
Multicultural Book - Children's Books
-
Arts and Crafts - Teacher Activities
-
Cooking Activities - Teacher Activities
-
Creative Activities - Teacher Activities
-
Preschool Activities - Teacher Activities
-
Child Guidance - Teacher Activities
-
Is there a way to further sort them so that each 'group' Children's Books or Teacher Activities would be in alphabetical order, so the result would be: -
Animals - Children's Books
-
Children and Their World - Children's Books
-
Families - Children's Books
-
Learning About Myself - Children's Books
-
Multicultural Book - Children's Books
-
Nature - Children's Books
-
Thinking Skills - Children's Books
-
Arts and Crafts - Teacher Activities
-
Child Guidance - Teacher Activities
-
Cooking Activities - Teacher Activities
-
Creative Activities - Teacher Activities
-
Preschool Activities - Teacher Activities
-
thanks
Paul
|  | Moderator | | Join Date: Oct 2006 Location: San Francisco, CA
Posts: 830
| | | re: Secondary sorting keys
Yes, just add the other conditions to your sorting function: -
open(BASE, $dbk) || do {&no_open;};
-
my @dbk = <BASE>;
-
close(BASE);
-
-
foreach my $line (sort cat @sorted) {
-
my @show = split ',', $line;
-
print "@show";
-
}
-
-
sub cat {
-
@x = split ',', $a;
-
@y = split ',', $b;
-
return ($x[2] cmp $y[2]) || ($x[0] cmp $y[0]);
-
}
-
- Miller
|  | Expert | | Join Date: Jan 2007 Location: Southern California USA
Posts: 4,091
| | | re: Secondary sorting keys
use a Schwartzian Transform: -
open (BASE, $dbk) || do {&no_open;};
-
@sorted = <BASE>;
-
close BASE;
-
@sortedNew = map {"$_->[0] - $->}[2]"}
-
sort {$a->[2] cmp $b->[2] || $a->[0] cmp $b->[0]}
-
map {chomp; [split(/,/)]} @sorted;
-
print "$_\n" for @sortedNew;
-
http://www.stonehenge.com/merlyn/UnixReview/col64.html |  | Expert | | Join Date: Jan 2007 Location: Southern California USA
Posts: 4,091
| | | re: Secondary sorting keys Quote:
Originally Posted by miller Yes, just add the other conditions to your sorting function: -
open(BASE, $dbk) || do {&no_open;};
-
my @dbk = <BASE>;
-
close(BASE);
-
-
foreach my $line (sort cat @sorted) {
-
my @show = split ',', $line;
-
print "@show";
-
}
-
-
sub cat {
-
@x = split ',', $a;
-
@y = split ',', $b;
-
return ($x[2] cmp $y[2]) || ($x[0] cmp $y[0]);
-
}
-
- Miller Looks like it would be fairly slow, but if the file is not big it may not matter.
| | Member | | Join Date: Jul 2007
Posts: 40
| | | re: Secondary sorting keys
thanks a lot!
many thanks
Paul
| | Member | | Join Date: Jul 2007
Posts: 40
| | | re: Secondary sorting keys
One more question.
The result of the sort is:
Animals - Children's Books
Children and Their World - Children's Books
Families - Children's Books
Learning About Myself - Children's Books
Multicultural Book - Children's Books
Nature - Children's Books
Thinking Skills - Children's Books
Arts and Crafts - Teacher Activities
Child Guidance - Teacher Activities
Cooking Activities - Teacher Activities
Creative Activities - Teacher Activities
Preschool Activities - Teacher Activities
which is perfect.
I have the output going into a table, is there a way to split the output to 2 columns instead of one long column.
I would like to have Children's Books displayed in the first column and Teachers Activities in the 2nd column.
I have tried a few things and all I get is something like this:
-------------[column 1]--------------------------------------------------[column 2]
Animals - Children's Books---------------------------------Arts and Crafts - Teacher Activities
Children and Their World - Children's Books-----------(blank cell)
Families - Children's Books--------------------------------(blank cell)
Learning About Myself - Children's Books---------------Child Guidance - Teacher Activities
Multicultural Book - Children's Books---------------------Cooking Activities - Teacher Activities
Nature - Children's Books-----------------------------------(blank cell)
Thinking Skills - Children's Books-------------------------Creative Activities - Teacher Activities
--------------------------------------------------------------------Preschool Activities - Teacher Activities
I'm sure I did it once, but maybe not.
Any help would be appreciated.
thanks
Paul
|  | Moderator | | Join Date: Oct 2006 Location: San Francisco, CA
Posts: 830
| | | re: Secondary sorting keys
For ultra simple text formatting, use sprintf: -
my @lines = (
-
"hello world - what'cha doing today?\n",
-
"foo bar baz biz lama lama - oh yeah\n",
-
"eek - more spacing tests\n",
-
);
-
-
foreach my $line (@lines) {
-
my ($col1, $col2) = split ' - ', $line;
-
print sprintf("%-30s %s", $col1, $col2);
-
}
-
- Miller
|  | Moderator | | Join Date: Oct 2006 Location: San Francisco, CA
Posts: 830
| | | re: Secondary sorting keys Quote:
Originally Posted by KevinADC Looks like it would be fairly slow, but if the file is not big it may not matter. I would call it just "slower". In truth, even for a large data file, I expect that the perl sorting and splitting functionality would be plenty fast enough for this to not be a noticable operation.
But either way, it just seemed simpler to avoid algorithmic efficiency discussions, and just focus on how one does this in a basic way. Yes, we probably wouldn't do it that way. But he didn't ask how we would, just how "one would". :)
- M
|  | Expert | | Join Date: Jan 2007 Location: Southern California USA
Posts: 4,091
| | | re: Secondary sorting keys Quote:
Originally Posted by deppeler I have tried a few things and all I get is something like this: Lets see something you have tried. "Table" could mean just about anything.
| | Member | | Join Date: Jul 2007
Posts: 40
| | | re: Secondary sorting keys
Here is one I tried: -
<table width='100%' border='1' cellpadding='1' cellspacing='1'>
-
HTML
-
open (BASE, $dbk) || do {&no_open;};
-
@sorted = <BASE>;
-
foreach $line (sort cat @sorted) {
-
@show = split(/,/,"$line");
-
$showta = "";
-
$showta = "$show[0]" if $show[2] eq 'Teacher and Activity Books';
-
$showcb = "";
-
$showcb = "$show[0]" if $show[2] eq 'Children`s Books';
-
print "<tr><td align='left' width='365'>$showta</td><td width='364'>$showcb</td></tr>";
-
}
-
close(BASE);
-
-
sub cat {
-
@x = split(/,/,$a);
-
@y = split(/,/,$b);
-
return ($x[2] cmp $y[2]) || ($x[0] cmp $y[0]);
-
}
-
-
print <<"HTML";
-
</table>
and this gives me an output of this: 
instead of this: 
thanks
Paul
|  | Expert | | Join Date: Jan 2007 Location: Southern California USA
Posts: 4,091
| | | re: Secondary sorting keys
what you want to do would best, or most easily, be accomplished by two arrays and using a different html table structure. This is untested and not meant to be a complete solution but I think it gives you the basic concept: - my @c = ();
-
my @t = ();
-
open (BASE, $dbk) || do {&no_open;};
-
my @sorted = <BASE>;
-
close (BASE);
-
foreach $line (@sorted) {
-
if ($line =~ /Teacher and Activity Books/) {
-
push @t, $line;
-
}
-
else {
-
push @c, $line;
-
}
-
}
-
@t = sort @t;
-
@c = sort @c;
-
my ($ctable,$ttable) = (q{<table width='100%' border='1'>}, q{<table width='100%' border='1'>});
-
for (@c){
-
$ctable .= qq{<tr><td>$_</td></tr>\n};
-
}
-
for (@t){
-
$ttable .= qq{<tr><td>$_</td></tr>\n};
-
}
-
$ctable .= '</table>';
-
$ttable .= '</table>';
-
print qq{<table width='100%' border='0' cellpadding='1' cellspacing='1'>
-
<tr>
-
<td valign="top" width="50%">
-
$ctable
-
</td>
-
<td valign="top" width="50%">
-
$ttable
-
</td>
-
</tr>
-
</table>\n};
this is not the way I would probably do it, but unless you are ready to get into references and more complex data structres, like a hash of arrays and such, then a solution like this while a little awkward is fairly straight forward to understand.
-Kevin
| | Member | | Join Date: Jul 2007
Posts: 40
| | | re: Secondary sorting keys
No that looks good except how do I stop it printing the entire line of the db?
I just want the field 1 & 2 and not the commas either.
It prints like this: Animals,ANIML,Children's Books,
I would like it to print like this: Animals - Children's Books
thanks a heap
Paul
|  | Expert | | Join Date: Jan 2007 Location: Southern California USA
Posts: 4,091
| | | re: Secondary sorting keys
Like I said, not a complete solution. Use split() to get the parts of the lines you want just like you have been doing in your previous code.
| | Member | | Join Date: Jul 2007
Posts: 40
| | | re: Secondary sorting keys
Ok I tried: - my @c = ();
-
my @t = ();
-
open (BASE, $dbk) || do {&no_open;};
-
my @sorted = <BASE>;
-
close (BASE);
-
foreach $line (@sorted) {
- @show = split ',', $line;
-
if ($line =~ /Teacher and Activity Books/) {
-
push @t, $line;
-
}
-
else {
-
push @c, $line;
-
}
-
}
-
@t = sort @t;
-
@c = sort @c;
-
my ($ctable,$ttable) = (q{<table width='362' border='0' cellpadding='3' cellspacing='1' align='center' bgcolor='#F5F5F5'>}, q{<table width='361' border='0' cellpadding='3' cellspacing='1' align='center' bgcolor='#F5F5F5'>});
-
for (@c){
-
$ctable .= qq{<tr><td>$show[0] - $show[2]</td></tr>\n};
-
}
-
for (@t){
-
$ttable .= qq{<tr><td>$show[0] - $show[2]</td></tr>\n};
-
}
-
$ctable .= '</table>';
-
$ttable .= '</table>';
-
print qq{<table width='729' border='0' cellpadding='3' cellspacing='1' align='center' bgcolor='#F5F5F5'>
-
<tr>
-
<td valign="top" width="50%">
-
$ctable
-
</td>
-
<td valign="top" width="50%">
-
$ttable
-
</td>
-
</tr>
-
</table>\n};
But I am only get the first line repeated.
What am I doing wrong?
thanks
|  | Expert | | Join Date: Jan 2007 Location: Southern California USA
Posts: 4,091
| | | re: Secondary sorting keys
You have a fundamental misunderstanding of the process. See how this works: - my @c = ();
-
my @t = ();
-
open (BASE, $dbk) || do {&no_open;};
-
my @sorted = <BASE>;
-
close (BASE);
-
foreach $line (@sorted) {
-
if ($line =~ /Teacher and Activity Books/) {
-
push @t, $line;
-
}
-
else {
-
push @c, $line;
-
}
-
}
-
@t = sort @t;
-
@c = sort @c;
-
my ($ctable,$ttable) = (q{<table width='100%' border='1'>}, q{<table width='100%' border='1'>});
-
for (@c){
-
my @temp = split(/,/);
-
$ctable .= qq{<tr><td>$temp[0] - $temp[2]</td></tr>\n};
-
}
-
for (@t){
-
my @temp = split(/,/);
-
$ttable .= qq{<tr><td>$temp[0] - $temp[2]</td></tr>\n};
-
}
-
$ctable .= '</table>';
-
$ttable .= '</table>';
-
print qq{<table width='100%' border='0' cellpadding='1' cellspacing='1'>
-
<tr>
-
<td valign="top" width="50%">
-
$ctable
-
</td>
-
<td valign="top" width="50%">
-
$ttable
-
</td>
-
</tr>
-
</table>\n};
|  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,392 network members.
|