Page 1 of 1
Sorting lists
Posted: Wed Apr 14, 2004 6:04 pm
by StumpDK
I'm creating a website which shows a list of results. The results are in an array.
I wan't the user to be able to sort the list by name, age, city and so on, by clicking on different links.
If 'name' is clicked and are already choosen, the list should sort descending instead of ascending and vice versa.
I've tried with my own code, and I end up with a lot of if-statements that doesn't seem to work.
Do you know any places where I can find examples of such scripts?
Or how would you do?
Posted: Wed Apr 14, 2004 6:25 pm
by lazy_yogi
http://au.php.net/manual/en/function.asort.php
checkout casort in the comments section.
someone made it and does what you want
Posted: Wed Apr 14, 2004 6:31 pm
by d3ad1ysp0rk
http://lps.no-ip.org/sortsource.php
LOTS of stuff to sift through, but it should give you a basic idea of what I did.
This was one of my first actual big scripts, so it's sloppy, doesn't use functions, and has logic/presentation all jammed up in one big pile of code.
Post here if you have any questions about it.
Posted: Wed Apr 14, 2004 8:14 pm
by McGruff
You mentioned results - presumably these are obtained from a db query? If so, all you need is an ORDER BY clause.
Best not to put real column names in a link (or a form): switch/case or if/else to map user input to db col names.
Posted: Thu Apr 15, 2004 3:13 am
by StumpDK
Thank you for your replies.
The reason why I'm not using the SQL-query Sort By is, that that would require a DB-query every time someone's sorting their list of results. To optimize the process, I move all of the results into an array, and then I'm doing the sorting.
I've looked at the functions you wrote about, and what I need now, is a function that decides how to the array.
McGruff talks about it's not good to use real coloumn names in a link or a form, but how would you do then?
Is it a switch:
switch($_GET['sort_by'])
case 'name':
<< Sorting by name >>
case 'age':
<< Sorting by age >>
Or how would you do it?
Posted: Thu Apr 15, 2004 3:27 am
by markl999
How are you storing the array inbetween page requests?
ie if you don't redo the query then how is the array 'regenerated', are you storing it in a session or something?
Posted: Thu Apr 15, 2004 3:35 am
by StumpDK
Yes... I'm using the $_SESSION to store the array between the pages...
Posted: Thu Apr 15, 2004 4:07 am
by markl999
Here's an example that uses a hardcoded array, but you should be able to adapt it to your array/rows from the db.
Code: Select all
<?php
session_start();
//list of columns titles, this makes the links easier
$columns = array('fname', 'lname');
//set the array if it's not already in the session
if(empty($_SESSION['list'])){
$_SESSION['list'] = array(
array('fname' => 'john', 'lname' => 'doe'),
array('fname' => 'zak', 'lname' => 'bloggs'),
array('fname' => 'john3', 'lname' => 'doe3')
);
}
//set the default order
$order = SORT_DESC;
//see if we need to 'flip' the order
if(!empty($_GET['sort_by'])){
if(substr($_GET['sort_by'], 0, 1) == 'd'){
$order = SORT_DESC;
} else {
$order = SORT_ASC;
}
$by = substr($_GET['sort_by'], 1);
} else {
$_GET['sort_by'] = 'fname';
}
//sort it
array_multisort($_SESSION['list'], $order);
//display it
?>
<table>
<tr>
<?php
foreach($columns as $col){
$link = ($_GET['sort_by'] == $col) ? 'd'.$col : $col;
echo '<td><a href="'.$_SERVER['PHP_SELF'].'?sort_by='.$link.'">'.$col.'</a></td>';
}
?>
</tr>
<?php
foreach($_SESSION['list'] as $row){
echo '<tr><td>'.$row['fname'].'</td><td>'.$row['lname'].'</td></tr>';
}
?>
</table>
Posted: Thu Apr 15, 2004 5:19 am
by StumpDK
Well, thanks alot! That code is very usefull...
What is your opinion on me choice of using a session-array instead of the DB-query?
Posted: Thu Apr 15, 2004 6:56 am
by redmonkey
Not sure if it's of any use but here is my non-casesensitive sorting function....
Code: Select all
function array_ncsort($array, $index, $flag = SORT_ASC)
{
for($i = 0, $asize = count($array); $i < $asize; $i++)
{
$sortarr[] = strtolower($array[$i][$index]);
}
array_multisort($sortarr, $flag, $array);
return($array);
}
Example usage.....
Code: Select all
$names = array(
array('fname' => 'Frank', 'lname' => 'Smith', 'age' => 25),
array('fname' => 'John', 'lname' => 'Doe', 'age' => 28),
array('fname' => 'Joe', 'lname' => 'Bloggs', 'age' => 32),
array('fname' => 'Able', 'lname' => 'Jones', 'age' => 24)
);
// sort by firstname A => Z
$sorted = array_ncsort($names, 'fname');
// sort by lastname Z => A
$sorted = array_ncsort($names, 'lname', SORT_DESC);
Posted: Thu Apr 15, 2004 6:57 am
by magicrobotmonkey
To optimize the process, I move all of the results into an array, and then I'm doing the sorting.
I'm not sure if that's an optimization for a couple of reasons.
1. DB's are designed for that sort of thing. I think it would take a lot less work for a bunch of queries using ORDERBY rather than some php sorting algorithm which will require a lot of memory (double the size of the array?) and a good bit of processing, whereas the DB is optimized for such things.
2. A large array like that will use a bunch of memory when passed from page to page.
I dunno, but on this one, I'd let the DB do the work. By the way, what sort algorithm are you using?
Posted: Thu Apr 15, 2004 1:46 pm
by StumpDK
Nice comments to the sorting thing. I'm not very much in to all this sorting thing, so I'm using array_multisort, but honestly, I don't know which one to use... Any ideas?
Posted: Thu Apr 15, 2004 2:28 pm
by McGruff
usort()
You'll need a callback function for each column you wish to sort on.
Posted: Thu Apr 15, 2004 4:59 pm
by d3ad1ysp0rk
I'd use SQL ORDERBY. Much faster.