note 95543 deleted from function.array-multisort by danbrown

From: Date: Fri, 08 Jan 2010 15:17:34 +0000
Subject: note 95543 deleted from function.array-multisort by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-164790@lists.php.net to get a copy of this message
Note Submitter: cagret at gmail dot com ---- 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; } ?>

« previous php.notes (#164790) next »