473,465 Members | 1,524 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Secondary sorting keys

40 New Member
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

Expand|Select|Wrap|Line Numbers
  1. open(BASE, $dbk) || do {&no_open;};
  2. my @sorted = <BASE>;
  3. close(BASE);
  4.  
  5. foreach my $line (sort cat @sorted) {
  6.     my @show = split ',', $line;
  7.  
  8.  
  9. ....
  10.  
  11. sub cat {
  12.     @x = split ',', $a;
  13.     @y = split ',', $b;
  14.     return ($x[2] cmp $y[2]);
  15. }
the result is:

Expand|Select|Wrap|Line Numbers
  1. Children and Their World - Children's Books
  2. Nature - Children's Books
  3. Animals - Children's Books
  4. Families - Children's Books
  5. Learning About Myself - Children's Books
  6. Thinking Skills - Children's Books
  7. Multicultural Book - Children's Books
  8. Arts and Crafts - Teacher Activities
  9. Cooking Activities - Teacher Activities
  10. Creative Activities - Teacher Activities
  11. Preschool Activities - Teacher Activities
  12. Child Guidance - Teacher Activities
  13.  

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:

Expand|Select|Wrap|Line Numbers
  1. Animals - Children's Books
  2. Children and Their World - Children's Books
  3. Families - Children's Books
  4. Learning About Myself - Children's Books
  5. Multicultural Book - Children's Books
  6. Nature - Children's Books
  7. Thinking Skills - Children's Books
  8. Arts and Crafts - Teacher Activities
  9. Child Guidance - Teacher Activities
  10. Cooking Activities - Teacher Activities
  11. Creative Activities - Teacher Activities
  12. Preschool Activities - Teacher Activities
  13.  
thanks
Paul
Jul 31 '07 #1
14 2689
miller
1,089 Recognized Expert Top Contributor
Yes, just add the other conditions to your sorting function:

Expand|Select|Wrap|Line Numbers
  1. open(BASE, $dbk) || do {&no_open;};
  2. my @dbk = <BASE>;
  3. close(BASE);
  4.  
  5. foreach my $line (sort cat @sorted) {
  6.     my @show = split ',', $line;
  7.     print "@show";
  8. }
  9.  
  10. sub cat {
  11.     @x = split ',', $a;
  12.     @y = split ',', $b;
  13.     return ($x[2] cmp $y[2]) || ($x[0] cmp $y[0]);
  14. }
  15.  
- Miller
Jul 31 '07 #2
KevinADC
4,059 Recognized Expert Specialist
use a Schwartzian Transform:

Expand|Select|Wrap|Line Numbers
  1. open (BASE, $dbk) || do {&no_open;};
  2. @sorted = <BASE>;
  3. close BASE;
  4. @sortedNew = map  {"$_->[0] - $->}[2]"}
  5.              sort {$a->[2] cmp $b->[2] || $a->[0] cmp $b->[0]}
  6.              map  {chomp; [split(/,/)]} @sorted;
  7. print "$_\n" for @sortedNew;
  8.  
http://www.stonehenge.com/merlyn/UnixReview/col64.html
Jul 31 '07 #3
KevinADC
4,059 Recognized Expert Specialist
Yes, just add the other conditions to your sorting function:

Expand|Select|Wrap|Line Numbers
  1. open(BASE, $dbk) || do {&no_open;};
  2. my @dbk = <BASE>;
  3. close(BASE);
  4.  
  5. foreach my $line (sort cat @sorted) {
  6.     my @show = split ',', $line;
  7.     print "@show";
  8. }
  9.  
  10. sub cat {
  11.     @x = split ',', $a;
  12.     @y = split ',', $b;
  13.     return ($x[2] cmp $y[2]) || ($x[0] cmp $y[0]);
  14. }
  15.  
- Miller
Looks like it would be fairly slow, but if the file is not big it may not matter.
Jul 31 '07 #4
deppeler
40 New Member
thanks a lot!
many thanks
Paul
Jul 31 '07 #5
deppeler
40 New Member
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
Jul 31 '07 #6
miller
1,089 Recognized Expert Top Contributor
For ultra simple text formatting, use sprintf:

Expand|Select|Wrap|Line Numbers
  1. my @lines = (
  2.     "hello world - what'cha doing today?\n",
  3.     "foo bar baz biz lama lama - oh yeah\n",
  4.     "eek - more spacing tests\n",
  5. );
  6.  
  7. foreach my $line (@lines) {
  8.     my ($col1, $col2) = split ' - ', $line;
  9.     print sprintf("%-30s %s", $col1, $col2);
  10. }
  11.  
- Miller
Jul 31 '07 #7
miller
1,089 Recognized Expert Top Contributor
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
Jul 31 '07 #8
KevinADC
4,059 Recognized Expert Specialist
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.
Jul 31 '07 #9
deppeler
40 New Member
Here is one I tried:

Expand|Select|Wrap|Line Numbers
  1. <table width='100%' border='1' cellpadding='1' cellspacing='1'>
  2. HTML
  3. open (BASE, $dbk) || do {&no_open;};
  4. @sorted = <BASE>;
  5. foreach $line (sort cat @sorted) {
  6.     @show = split(/,/,"$line");
  7.     $showta = "";
  8.     $showta = "$show[0]" if $show[2] eq 'Teacher and Activity Books';
  9.     $showcb = "";
  10.     $showcb = "$show[0]" if $show[2] eq 'Children`s Books';
  11.     print "<tr><td align='left' width='365'>$showta</td><td width='364'>$showcb</td></tr>";
  12. }
  13. close(BASE);
  14.  
  15. sub cat {
  16.     @x = split(/,/,$a);
  17.     @y = split(/,/,$b);
  18.     return ($x[2] cmp $y[2]) || ($x[0] cmp $y[0]);
  19. }
  20.  
  21. print <<"HTML";
  22. </table>

and this gives me an output of this:



instead of this:



thanks
Paul
Aug 1 '07 #10
KevinADC
4,059 Recognized Expert Specialist
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:

Expand|Select|Wrap|Line Numbers
  1. my @c = ();
  2. my @t = ();
  3. open (BASE, $dbk) || do {&no_open;};
  4. my @sorted = <BASE>;
  5. close (BASE);
  6. foreach $line (@sorted) {
  7.    if ($line =~ /Teacher and Activity Books/) {
  8.       push @t, $line;
  9.    }
  10.    else {
  11.       push @c, $line;
  12.    }
  13. }
  14. @t = sort @t;
  15. @c = sort @c;
  16. my ($ctable,$ttable) = (q{<table width='100%' border='1'>}, q{<table width='100%' border='1'>});
  17. for (@c){
  18.    $ctable .= qq{<tr><td>$_</td></tr>\n};
  19. }
  20. for (@t){
  21.    $ttable .= qq{<tr><td>$_</td></tr>\n};
  22. }
  23. $ctable .= '</table>';
  24. $ttable .= '</table>';
  25. print qq{<table width='100%' border='0' cellpadding='1' cellspacing='1'>
  26.  <tr>
  27.   <td valign="top" width="50%">
  28.     $ctable
  29.   </td>
  30.   <td valign="top" width="50%">
  31.     $ttable
  32.   </td>
  33.  </tr>
  34. </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
Aug 1 '07 #11
deppeler
40 New Member
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
Aug 1 '07 #12
KevinADC
4,059 Recognized Expert Specialist
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.
Aug 1 '07 #13
deppeler
40 New Member
Ok I tried:

Expand|Select|Wrap|Line Numbers
  1. my @c = ();
  2. my @t = ();
  3. open (BASE, $dbk) || do {&no_open;};
  4. my @sorted = <BASE>;
  5. close (BASE);
  6. foreach $line (@sorted) {
  7. @show = split ',', $line;
  8.    if ($line =~ /Teacher and Activity Books/) {
  9.       push @t, $line;
  10.    }
  11.    else {
  12.       push @c, $line;
  13.    }
  14. }
  15. @t = sort @t;
  16. @c = sort @c;
  17. 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'>});
  18. for (@c){
  19.    $ctable .= qq{<tr><td>$show[0] - $show[2]</td></tr>\n};
  20. }
  21. for (@t){
  22.    $ttable .= qq{<tr><td>$show[0] - $show[2]</td></tr>\n};
  23. }
  24. $ctable .= '</table>';
  25. $ttable .= '</table>';
  26. print qq{<table width='729' border='0' cellpadding='3' cellspacing='1' align='center' bgcolor='#F5F5F5'>
  27.  <tr>
  28.   <td valign="top" width="50%">
  29.     $ctable
  30.   </td>
  31.   <td valign="top" width="50%">
  32.     $ttable
  33.   </td>
  34.  </tr>
  35. </table>\n};

But I am only get the first line repeated.
What am I doing wrong?

thanks
Aug 1 '07 #14
KevinADC
4,059 Recognized Expert Specialist
You have a fundamental misunderstanding of the process. See how this works:

Expand|Select|Wrap|Line Numbers
  1. my @c = ();
  2. my @t = ();
  3. open (BASE, $dbk) || do {&no_open;};
  4. my @sorted = <BASE>;
  5. close (BASE);
  6. foreach $line (@sorted) {
  7.    if ($line =~ /Teacher and Activity Books/) {
  8.       push @t, $line;
  9.    }
  10.    else {
  11.       push @c, $line;
  12.    }
  13. }
  14. @t = sort @t;
  15. @c = sort @c;
  16. my ($ctable,$ttable) = (q{<table width='100%' border='1'>}, q{<table width='100%' border='1'>});
  17. for (@c){
  18.    my @temp = split(/,/);
  19.    $ctable .= qq{<tr><td>$temp[0] - $temp[2]</td></tr>\n};
  20. }
  21. for (@t){
  22.    my @temp = split(/,/);
  23.    $ttable .= qq{<tr><td>$temp[0] - $temp[2]</td></tr>\n};
  24. }
  25. $ctable .= '</table>';
  26. $ttable .= '</table>';
  27. print qq{<table width='100%' border='0' cellpadding='1' cellspacing='1'>
  28.  <tr>
  29.   <td valign="top" width="50%">
  30.     $ctable
  31.   </td>
  32.   <td valign="top" width="50%">
  33.     $ttable
  34.   </td>
  35.  </tr>
  36. </table>\n}; 
Aug 2 '07 #15

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: shalendra chhabra | last post by:
Hi, I just had a tryst with python. I was wondering if python is good enough to do this kind of job -- for it has extensive support of string and pattern matching, ordering and list handling. ...
4
by: dont bother | last post by:
This is really driving me crazy. I have a dictionary feature_vectors{}. I try to sort its keys using #apply sorting on feature_vectors sorted_feature_vector=feature_vectors.keys()...
13
by: Paul | last post by:
Hi all I have a sorting problem, but my experience with Python is rather limited (3 days), so I am running this by the list first. I have a large database of 15GB, consisting of 10^8 entries...
1
by: David Pratt | last post by:
I have been using the following for sorting a list of dictionaries. This works but only provides sorting on a single key. I am wanting to extend this with a better comparison expression so that it...
7
by: Karin Jensen | last post by:
Hi I am running a PHP program that connects to an Access 2000 database via ODBC: $results = odbc_exec($connection_id, $sql_select); Is it possible to sort the contents of $results? I wish to...
6
by: Fred Morrison | last post by:
Do you know of a way to load a hash table with random key/value pairs (e.g., 2/"Two",1/"One",3/"Three") and then iterate through the entries in "sorted" (key sequence) order...
5
by: (PeteCresswell) | last post by:
User's screen has a "Sort By" option group on it with radio buttons for things like "Deal Name", "Collateral Manager", "Underwriter", Closing Date", "Holding Size", and so-on and so-forth. But...
11
by: garyhoran | last post by:
Hi Guys, I have a collection that contains various attributes (stuff like strings, DateTime and Timespan) . I would like to access the collection in various orders at different points in the...
1
KevinADC
by: KevinADC | last post by:
Introduction In part one we discussed the default sort function. In part two we will discuss more advanced techniques you can use to sort data. Some of the techniques might introduce unfamiliar...
3
KevinADC
by: KevinADC | last post by:
If you are entirely unfamiliar with using Perl to sort data, read the "Sorting Data with Perl - Part One and Two" articles before reading this article. Beginning Perl coders may find this article...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.