Sorting arrays... reversing the order...

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Mr Tech
Forum Contributor
Posts: 424
Joined: Tue Aug 10, 2004 3:08 am

Sorting arrays... reversing the order...

Post 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?
User avatar
iknownothing
Forum Contributor
Posts: 337
Joined: Sun Dec 17, 2006 11:53 pm
Location: Sunshine Coast, Australia

Post by iknownothing »

use

Code: Select all

rsort
as apposed to...

Code: Select all

usort
User avatar
Mr Tech
Forum Contributor
Posts: 424
Joined: Tue Aug 10, 2004 3:08 am

Post 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?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

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

Post 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');
(#10850)
User avatar
Mr Tech
Forum Contributor
Posts: 424
Joined: Tue Aug 10, 2004 3:08 am

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

Post 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?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

Did you look carefully at the code I posted compared to the code you originally posted? Did you try it?
(#10850)
josa
Forum Commoner
Posts: 75
Joined: Mon Jun 24, 2002 4:58 am
Location: Sweden

Post 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
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Arborint gave you the answer. Try his code.
josa
Forum Commoner
Posts: 75
Joined: Mon Jun 24, 2002 4:58 am
Location: Sweden

Post 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
User avatar
Mr Tech
Forum Contributor
Posts: 424
Joined: Tue Aug 10, 2004 3:08 am

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

Post 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 ;)
Post Reply