Gossamer Forum
Home : Products : Gossamer Links : Version 1.x :

Link sort order in categorys

Quote Reply
Link sort order in categorys
Hi all,

I have changed in Links.pm:

$LINKS{build_sort_order_category} = "Rating DESC,isNew,Add_Date DESC";

The function build_sort_links in nph-build.cgi works fine to sort strings.

But it compares numeric values like strings.

eg. My sort order is 'Rating' the sub gets the values
( 1.2, 9.4, 3.1, 10.0, 4.2, 5.0, 1.1) and sorts them to:
(10.0, 1.1, 1.2, 3.1, 4.2, 5.0, 9.4)

How can I make it sort numeric???

regards, alexander

Quote Reply
Re: Link sort order in categorys In reply to
I never noticed this. It seemed to be hidden in the alt-links problem for me.

The variable is passed to the MySQL database directly, so it's not a part of the Links code.

I skimmed into the MySQL book, and didn't see it, you might want to check the docs at http://www.mysql.org



http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/

Quote Reply
Re: Link sort order in categorys In reply to
No it isn't. Pearl uses the the ASCII comparison as the standard sort method in its function sort().

the sub build_sort_links uses this line of code to merge and sort the two arrays:

my @c = sort { lc join ("", @{$a}[@fields]) cmp lc join ("", @{$b}[@fields]) } @{$arr_b}, @{$arr_a};

where the sort criteria is in the array @fields (Rating, Hits, Votes)

To force the sort routine to sort numeric it has to be called this way:

@sorted= sort {$a <=> $b} @unsorted;

Is there anybody out there who can translate the first line of code and modify it to the numeric sort?

regards, alexander

Quote Reply
Re: Link sort order in categorys In reply to
That routine is for merging the alt-links with the regular links.

If you don't have any alt-links (and you can't, if you want the sort to work properly) just bypass that function call.

The links will come out of the MySQL database (hopefully) in the right order, based on the original "SELECT" statement.

INT fields should be sorted as INT's, and CHAR fields as CHAR.



http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/

Quote Reply
Re: Link sort order in categorys In reply to
A "fix" for this if you want to incur a performance hit, is to create another table. Insert the original select statement into it, then insert the alt-select into it.

Then, select ALL the links from this new table, in the &build_sort_order order.

All the links should then be sorted properly.

You need to then delete this table, or erase it's data. Since a link should only be in any category once, you shouldn't get any errors, but you could always insert the alt-links one-by-one checking for errors.

There are other "logical" ways to do it, but this is the quick and dirty one.



http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/

Quote Reply
Re: Link sort order in categorys In reply to
sub build_sort_links {
# --------------------------------------------------------
# Merges two array refs into one link list.
#
my ($arr_a, $arr_b) = @_;
my @names = split /,/, $LINKS{build_sort_order_category};
my @fields = map { $LINKDB->position($_) - 1 } @names;
my @c = sort { lc join ("", @{$a}[@fields]) cmp lc join ("", @{$b}[@fields]) } @{$arr_b}, @{$arr_a};
return \@c;
}

The problem i see: If you convert this to compare numbers; you will get for all strings the value of 0.
So there must be an "if then" like:
if the string is only 1,2,3,4,5,6,7,8,9,0,. #then its a number
else do normal.
The rexep for this should be something like: ^\d*\.?\d*$

Robert



Quote Reply
Re: Link sort order in categorys In reply to
The problem is that perl is non-typed. It doesn't make a distinction between "1" as an integer and "1" as a string. It decides the value in the "context" that it's working in. "eq" would be a string, and "=" would _probably_ be an integer compare.

The only way to FORCE an integer compare would be to preface the field with int() --- The only real way to guarantee it's a number compare is probably to use a mathematical operator on it ... such as $total = $varable_value_is_1 + 12 to get 13.

This is a subtlty of perl and trickery that I have to admit I'm not intimately familiar with. You might want to ask this on the perl board, since there are probably others who might know how to force that to happen who read there.

The reason it would be smoother to do inside MySQL and temporary tables, is that MySQL _is_ typed, and it would (should) watch how it makes integer vs string comparasons. Additionally, you'd get alt-links in order.



http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/