Page 1 of 1
Using multisort on a single array?
Posted: Fri Aug 24, 2007 2:18 pm
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"?
Posted: Fri Aug 24, 2007 2:56 pm
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'
),
),
*/
Posted: Fri Aug 24, 2007 3:04 pm
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;'));
Posted: Fri Aug 24, 2007 3:07 pm
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?
Posted: Fri Aug 24, 2007 3:09 pm
by John Cartwright
See my post above.
Posted: Fri Aug 24, 2007 3:17 pm
by Citizen
What exactly does that do?
(I'd rather learn than just copy+paste your code

)
Posted: Fri Aug 24, 2007 3:18 pm
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;
}
Posted: Fri Aug 24, 2007 3:26 pm
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

Posted: Fri Aug 24, 2007 3:27 pm
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.
Posted: Fri Aug 24, 2007 3:28 pm
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*
Posted: Fri Aug 24, 2007 3:35 pm
by Citizen
Thanks for the help everyone?
One final question, what exactly is this part doing?
Posted: Fri Aug 24, 2007 3:48 pm
by VladSun
It is an eqivalent to:
Code: Select all
if ($a['rank'] <= $b['rank']) return -1;
else return 1;