#6344: msort function added to the Set class to help with array sorting using multiple column parameters --------------------------+------------------------------------------------- Reporter: ebadedude | Type: Enhancement Status: new | Priority: Medium Milestone: 1.3.x.x | Component: Core Libs Version: 1.2 Final | Severity: Normal Keywords: | Php_version: n/a Cake_version: | --------------------------+------------------------------------------------- I needed the ability to sort an array using multiple columns criteria. the Set class has a "sort" function but it only takes one "$path/$dir" criterion. "msort" takes an array of "$path/$dir" criteria. I am not sure about the usefulness of this functionality, but I felt I should share. Also, the code could be enhanced upon as this is the first version.
Set Class Addition: {{{ /** * NOTE: similar to sort but returns two arrays * Sorts an array by any value, determined by a Set-compatible path * * @param array $data * @param string $path A Set-compatible path to the array value * @param string $dir asc/desc * @return array [sorted] - Sorted Array * [section] - Sorted Array seperated by similar groupings * @static */ function sort2($data, $path, $dir) { $sortedSections = array(); $result = Set::__flatten(Set::extract($data, $path)); list($keys, $values) = array(Set::extract($result, '{n}.id'), Set::extract($result, '{n}.value')); $dir = strtolower($dir); if ($dir === 'asc') { $dir = SORT_ASC; } elseif ($dir === 'desc') { $dir = SORT_DESC; } array_multisort($values, $dir, $keys, $dir); $sorted = array(); $keys = array_unique($keys); $sectArr = array(); //Store sorted section groupings $prevVal = ''; //Used for comparison $count = 0; foreach ($keys as $k) { if($count == 0) { $sectArr[] = $data[$k]; $prevVal = $values[$count]; } else { if($prevVal == $values[$count]) { $sectArr[] = $data[$k]; } else { $sortedSections[] = $sectArr; $sectArr = array(); $sectArr[] = $data[$k]; } $prevVal = $values[$count]; } $sorted[] = $data[$k]; $count++; } $sortedSections[] = $sectArr; return array('sorted' => $sorted, 'sectioned' => $sortedSections); } /** * Sorts an array by an array of multiple values, determined by a Set- compatible path * Similar to sort but takes an array of $path and $dir instead of single values * Usage example -> Set::msort($data, array('{n}.vname'=>'DESC','{n}.pname'=>'DESC')) * * @param array $data * @param array $patharr An array of Set-compatible path to the array value * @return array * @static */ function msort($data, $patharr) { $sorted = $data; if(!is_array($patharr)) return $sorted; $sortedSectArr = array($data); foreach($patharr as $path => $dir) { $tmpSorted = array(); //Stores temporary list of sorted array $tmpSectionSorted = array(); //Stores temporary list of sorted array grouped by current sorting path foreach($sortedSectArr as $data2) { $res = Set::sort2($data2, $path, $dir); $tmpSorted[] = $res['sorted']; $tmpSectionSorted[] = $res['sectioned']; } //Generate new sorted list $sorted = array(); foreach($tmpSorted as $sortedArr) { foreach($sortedArr as $sorted2) { $sorted[] = $sorted2; } } $sortedSectArr = array(); foreach($tmpSectionSorted as $sectionLvl) { foreach($sectionLvl as $sectionLvl2) { $sortedSectArr[] = $sectionLvl2; } } } return $sorted; } }}} Usage (In Controller): {{{ $data = Array( Array( 'vid' => 1, 'vname' => 'Test Entry V1', 'pid' => 1, 'pname' => 'Test Entry P1', 'yid' => 1, 'yname' => 'Test Entry Y1' ), Array( 'vid' => 2, 'vname' => 'Test Entry V2', 'pid' => 2, 'pname' => 'Test Entry P0', 'yid' => 2, 'yname' => 'Test Entry Y2' ), Array( 'vid' => 3, 'vname' => 'Test Entry V1', 'pid' => 3, 'pname' => 'Test Entry P2', 'yid' => 2, 'yname' => 'Test Entry Y2' ) ); $res1 = Set::msort($data,array('{n}.vname'=>'DESC','{n}.pname'=>'DESC')); $res2 = Set::msort($data,array('{n}.vname'=>'DESC','{n}.pname'=>'ASC')); //Result $res1 = Array ( [0] => Array ( [vid] => 2 [vname] => Test Entry V2 [pid] => 2 [pname] => Test Entry P0 [yid] => 2 [yname] => Test Entry Y2 ) [1] => Array ( [vid] => 3 [vname] => Test Entry V1 [pid] => 3 [pname] => Test Entry P2 [yid] => 2 [yname] => Test Entry Y2 ) [2] => Array ( [vid] => 1 [vname] => Test Entry V1 [pid] => 1 [pname] => Test Entry P1 [yid] => 1 [yname] => Test Entry Y1 ) ) $res2 = Array ( [0] => Array ( [vid] => 2 [vname] => Test Entry V2 [pid] => 2 [pname] => Test Entry P0 [yid] => 2 [yname] => Test Entry Y2 ) [1] => Array ( [vid] => 1 [vname] => Test Entry V1 [pid] => 1 [pname] => Test Entry P1 [yid] => 1 [yname] => Test Entry Y1 ) [2] => Array ( [vid] => 3 [vname] => Test Entry V1 [pid] => 3 [pname] => Test Entry P2 [yid] => 2 [yname] => Test Entry Y2 ) ) }}} -- Ticket URL: <https://trac.cakephp.org/ticket/6344> CakePHP : The Rapid Development Framework for PHP <https://trac.cakephp.org/> Cake is a rapid development framework for PHP which uses commonly known design patterns like ActiveRecord, Association Data Mapping, Front Controller and MVC. Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "tickets cakephp" group. To post to this group, send email to tickets-cakephp@googlegroups.com To unsubscribe from this group, send email to tickets-cakephp+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/tickets-cakephp?hl=en -~----------~----~----~----~------~----~------~--~---