Page 1 of 1

Sorting arrays... reversing the order...

Posted: Mon Aug 20, 2007 11:48 pm
by Mr Tech
I have an array I want to sort by 'date_history'. The format of the date is yyyy-mm-dd hh:mm:ss.

I found this code which sorts the date_history:

Code: Select all

function sort_history($a, $b) { 
	return strnatcmp($a['date_history'], $b['date_history']); 
} 
usort($history_items, 'sort_history');
However it shows the oldest dates first the and newest dates last. I need to reverse that so it shows the newest dates first and the oldest dates last.

Any ideas how I'd do that?

Posted: Mon Aug 20, 2007 11:57 pm
by iknownothing
use

Code: Select all

rsort
as apposed to...

Code: Select all

usort

Posted: Tue Aug 21, 2007 12:05 am
by Mr Tech
Thanks for your quick reply!

I tried rsort using this code:

Code: Select all

rsort($history_items, 'sort_history');
But it gives this error:

Warning: rsort() expects parameter 2 to be long, string given in /var/flexshare/shares/php/development/crm/modules/clients/history.php on line 430

I then tried this:

Code: Select all

rsort($history_items);
And it doesn't sort it right.

According the the PHP docs it says:

Code: Select all

bool rsort ( array &$array [, int $sort_flags] )
Is there something specific I need to put in the int $sort_flags section of the function?

Re: Sorting arrays... reversing the order...

Posted: Tue Aug 21, 2007 12:11 am
by Christopher
usort() sorts based on the function you give it. So make the function do the opposite and you will get a reverse sort:

Code: Select all

function rsort_history($a, $b) { 
	return strnatcmp($b['date_history'], $a['date_history']); 
} 
usort($history_items, 'rsort_history');

Re: Sorting arrays... reversing the order...

Posted: Tue Aug 21, 2007 12:21 am
by Mr Tech
arborint wrote:usort() sorts based on the function you give it. So make the function do the opposite and you will get a reverse sort:

Code: Select all

function rsort_history($a, $b) { 
	return strnatcmp($b['date_history'], $a['date_history']); 
} 
usort($history_items, 'rsort_history');
Sorry to be so stupid. I wouldn't know what function I gave it. I found the code on a website and adapted it to suit me.

Basically my array looks something like this:

Code: Select all

$history_items = array();

$history_items[0]['id'] = "1";
$history_items[0]['date_history'] = "2007-08-20 13:04:57";
$history_items[0]['name'] = "test1";
$history_items[0]['details'] = "this is a test";

$history_items[1]['id'] = "2";
$history_items[1]['date_history'] = "2007-08-18 09:23:01";
$history_items[1]['name'] = "test2";
$history_items[1]['details'] = "this is a test as well";

$history_items[2]['id'] = "3";
$history_items[2]['date_history'] = "2007-08-21 12:11:01";
$history_items[2]['name'] = "test3";
$history_items[2]['details'] = "this is a test even more than the first two";

etc.. etc...
Basically I want the array to sort by the date_history. Newest to oldest. That code I first gave you almost does the trick however it shows it oldest to newest.

Does that make more sense?

Posted: Tue Aug 21, 2007 12:52 am
by Christopher
Did you look carefully at the code I posted compared to the code you originally posted? Did you try it?

Posted: Tue Aug 21, 2007 2:44 am
by josa
Hi!

Your array is multidimensional so the sort and natsort functions are not going to behave the way you want. My php skills are a bit rusty, but I managed to put together this function:

Code: Select all

function natsubsort(&$arr, $sub_key, $reverse = false) {
    $sub_arr = array();
    foreach ($arr as $key => $value) {
        $sub_arr[$key] = $value[$sub_key];
    }
    if (!natsort($sub_arr)) {
        return false;
    }
    if ($reverse) {
        $sub_arr = array_reverse($sub_arr, true); 
    }
    $sorted_arr = array();
    foreach ($sub_arr as $key => $value) {
        $sorted_arr[] = $arr[$key];
    }
    $arr = $sorted_arr;
    return true;
}
I wrote this in a hurry this morning without doing any research, so if anyone has a better solution please post it here. I bet it can be optimized further. This is how you would use it on your array:

Code: Select all

natsubsort($history_items, 'date_history', true);
It can't handle sorting by more than one sub key and it can't handle arrays with more than two dimensions.

/josa

Posted: Tue Aug 21, 2007 2:58 am
by RobertGonzalez
Arborint gave you the answer. Try his code.

Posted: Tue Aug 21, 2007 6:24 am
by josa
I really don't know what I was thinking. Read the whole post, make sure you understand the problem then reply. Got it! :)
Listen to arborint and ignore my post.

/josa

Re: Sorting arrays... reversing the order...

Posted: Tue Aug 21, 2007 6:35 pm
by Mr Tech
arborint wrote:usort() sorts based on the function you give it. So make the function do the opposite and you will get a reverse sort:

Code: Select all

function rsort_history($a, $b) { 
	return strnatcmp($b['date_history'], $a['date_history']); 
} 
usort($history_items, 'rsort_history');
Mate, how could I be so blind... Yes, arborint's code did work. I failed to notice you switched the b and the a around. I thought you gave me exactly the same code but just added the letter r to the start of the functions.

Much appreciated!!! 8)

Also, thanks for your code too josa ;)