Using multisort on a single array?

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
Citizen
Forum Contributor
Posts: 300
Joined: Wed Jul 20, 2005 10:23 am

Using multisort on a single array?

Post by Citizen »

I've completely read through php.net's guide for sort() and array_multisort and the examples and I still haven't figured out how to do this...


Basically, I have an array setup like:

Code: Select all

$query_array[$i]['id'] = $row[id];
$query_array[$i]['time'] = $row[time];
$query_array[$i]['votes'] = $row[votes];
$rank = $query_array[$i]['votes'] / (time() - $query_array[$i]['time']);
$query_array[$i]['rank']  = $rank;
How can I order this array descending depending on the "rank" and not the "id"?
User avatar
Zoxive
Forum Regular
Posts: 974
Joined: Fri Apr 01, 2005 4:37 pm
Location: Bay City, Michigan

Post by Zoxive »

Usually with questions like these, it depends mostly how you are building the array, and usually you can Build it Differently, and more efficiently.

Example if you were getting it from a Mysql Database:

Code: Select all

$Array = array();
$field='Rank';
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
  $name = $row[$field];
  $Array[$name][] = $row;
}

/*
'Rank1'=>
  array (
    0 => 
    array (
      'id' => 21
      'Name' => 'Name',
      'Type' => 'varchar(45)',
      'Rank'=> 'Rank1'
    ),
    1 => 
    array (
      'id' => 25
      'Name' => 'Name',
      'Type' => 'varchar(45)',
      'Rank'=> 'Rank1'
    ),
  ),
'Rank2=>
  array (
    0 => 
    array (
      'id' => 23
      'Name' => 'Name',
      'Type' => 'varchar(45)',
      'Rank'=> 'Rank2'
    ),
  ),
*/
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

Another way is to apply a callback function

Code: Select all

uasort($query_array, create_function('$a, $b', 'return ($a["rank"] <= $b["rank"]) ? -1 : 1;'));
Citizen
Forum Contributor
Posts: 300
Joined: Wed Jul 20, 2005 10:23 am

Post by Citizen »

Right.

The above code is just an example.

Basically what I meant is that I'm creating a key value for each row after the query has been received and want to sort using the new key instead of something that would sortable during the query.

So, the array value "rank" is not coming from the database. Its being created after.

Any ideas?
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

See my post above.
Citizen
Forum Contributor
Posts: 300
Joined: Wed Jul 20, 2005 10:23 am

Post by Citizen »

What exactly does that do?

(I'd rather learn than just copy+paste your code :))
User avatar
Zoxive
Forum Regular
Posts: 974
Joined: Fri Apr 01, 2005 4:37 pm
Location: Bay City, Michigan

Post by Zoxive »

Mine was an example also, if you were pulling from the database, and even implementing what you want isn't that hard..

Code: Select all

while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
  $name = $row['votes'] / (time() - $row['time']); 
  $Array[$name][] = $row;
} 
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

If I've said it once I've said it 100 times: array_multisort() is a powerful but mysterious beast.

Basically what you do is make a new array of just the ranks, with the same ids. So the array would be like:

Code: Select all

array[0]=>rank from $query_array[0]['rank']
     [1]=>rank from $query_array[1]['rank']
     ...etc
then throw it in array_multisort(), something like:

Code: Select all

array_multisort($newly_created_rank_array,SORT_DESC,$query_array,$query_array);
That's the way I've used array_multisort() in the past & it works. Not 100% sure how or why though :?
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

uasort — Sort an array with a user-defined comparison function and maintain index association
Pretty much, uasort accepts a user defined function to determine the way you want to sort your array. Since your sort is a bit irregular, I thought it best to create a custom function. For clarities sake, it could be re-written as

Code: Select all

function customsort($a, $b) {
   return ($a['rank'] <= $b['rank'] ? -1 : 1);
} 

uasort($query_array, 'customsort');
However I prefer the usage of create_function, especially when you need to define different columns to sort by.
Last edited by John Cartwright on Fri Aug 24, 2007 3:29 pm, edited 1 time in total.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

pickle wrote:If I've said it once I've said it 100 times: array_multisort() is a powerful but mysterious beast.
That is quite true, I've never really used array_multisort() due to it's *mysterious nature*
Citizen
Forum Contributor
Posts: 300
Joined: Wed Jul 20, 2005 10:23 am

Post by Citizen »

Thanks for the help everyone?

One final question, what exactly is this part doing?

Code: Select all

$a['rank'] <= $b['rank'] ? -1 : 1
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Post by VladSun »

It is an eqivalent to:

Code: Select all

if ($a['rank'] <= $b['rank']) return -1;
else return 1;
There are 10 types of people in this world, those who understand binary and those who don't
Post Reply