note 95543 added to function.array-multisort
| From: | cagret at gmail dot com | Date: | Fri, 08 Jan 2010 07:10:24 +0000 |
| Subject: | note 95543 added to function.array-multisort | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-164774@lists.php.net to get a copy of this message | ||
d_inkubus at yahoo dot com 21-Dec-2009 11:33:
There is a bug in your update to array_msort():
<?php
foreach($order as $order_element) {
$params[]=&$order_element;
}
?>
You are making a reference to a local loop variable that will change through the loop.
It's going to work ok when you sort only by 1 column:
<?php
$refs = array_msort($refs, array('hits'=>SORT_DESC));
?>
>>$order_element == SORT_DESC
But when you sort by multiple columns:
<?php
$refs = array_msort($refs, array('hits'=>SORT_DESC, 'uri'=>SORT_ASC,
'from'=>SORT_ASC));
?>
>>hits $order_element == SORT_ASC, uri $order_element == SORT_ASC, from $order_element ==
>>SORT_ASC
It even gets more complicated if you provide more flags.
After foreach is executed $order_element contains the last value, seems like this will solve the
problem:
<?php
foreach($order as $k => $order_element) {
$params[] =& $order[$k];
}
?>
But no, because that loop is inside another loop, so $order is also a local loop variable.
The solution:
<?php
foreach ($cols as $col => $order) {
$params[] =& $colarr[$col];
$cols[$col] = (array) $cols[$col];
foreach ($cols[$col] as $k => $ordval) {
$params[] =& $cols[$col][$k];
}
}
?>
The final version of array_msort:
<?php
function array_msort($array, $cols)
{
// Example: $arr2 = array_msort($arr1, array('name'=>array(SORT_ASC,SORT_REGULAR),
'cat'=>SORT_DESC));
$colarr = array();
foreach ($cols as $col => $order) {
$colarr[$col] = array();
foreach ($array as $k => $row) {
$colarr[$col]['_'.$k] = strtolower($row[$col]);
}
}
$params = array();
foreach ($cols as $col => $order) {
$params[] =& $colarr[$col];
$cols[$col] = (array) $cols[$col];
foreach ($cols[$col] as $k => $ordval) {
$params[] =& $cols[$col][$k];
}
}
call_user_func_array('array_multisort', $params);
$ret = array();
$keys = array();
$first = true;
foreach ($colarr as $col => $arr) {
foreach ($arr as $k => $v) {
if ($first) {
$keys[$k] = substr($k, 1);
}
$k = $keys[$k];
if (!isset($ret[$k])) {
$ret[$k] = $array[$k];
}
$ret[$k][$col] = $array[$k][$col];
}
$first = false;
}
return $ret;
}
?>
----
Server IP: 82.177.164.100
Probable Submitter: 213.238.94.77
----
Manual Page -- http://www.php.net/manual/en/function.array-multisort.php
Edit -- https://master.php.net/note/edit/95543
Del: integrated -- https://master.php.net/note/delete/95543/integrated
Del: useless -- https://master.php.net/note/delete/95543/useless
Del: bad code -- https://master.php.net/note/delete/95543/bad+code
Del: spam -- https://master.php.net/note/delete/95543/spam
Del: non-english -- https://master.php.net/note/delete/95543/non-english
Del: in docs -- https://master.php.net/note/delete/95543/in+docs
Del: other reasons-- https://master.php.net/note/delete/95543
Reject -- https://master.php.net/note/reject/95543
Search -- https://master.php.net/manage/user-notes.php