#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
-~----------~----~----~----~------~----~------~--~---

  • [CakePHP : The Rapid Dev... CakePHP : The Rapid Development Framework for PHP

Reply via email to