Last active
April 29, 2016 13:46
-
-
Save romellem/3cc96245671fc7ef63e84aa7d6dabb31 to your computer and use it in GitHub Desktop.
Helper function to Sort an array of objects by multiple keys.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Takes an array of objects, and sorts them by one or more keys. | |
* @param array &$list A one-dimensional array of objects | |
* @param array $keys Array of strings corresponding to the keys which we want to sort on. | |
* @param array $keys_order Optional array of strings for the sort order. Valid values are 'asc' or 'desc'. | |
* Placement corresponds to our $keys array (So $keys = ['a', 'b'] and $keys_order - ['desc', 'asc'] | |
* Will sort $list by key 'a' first in descending order, then by key 'b' in ascdening order). | |
* Default sort order will be SORT_ASC. | |
* @param array $key_flags Optional array of strings for the sort flags. | |
* Defaults to SORT_REGULAR. | |
* @return bool Returns false if $list or $keys is unset and null, or if array_multisort fails. | |
* Returns true if multisort is successful. | |
*/ | |
function _sortByOrder(&$list, $keys, $keys_order = null, $key_flags = null) { | |
if (!isset($list) || !isset($keys)) { | |
return false; | |
} | |
/** | |
* Array of "cols" within our list. | |
* | |
* So... | |
* | |
* $list = [ | |
* ['a' => 0, 'b' => 1], | |
* ['a' => 2, 'b' => 3], | |
* ['a' => 4, 'b' => 5] | |
* ]; | |
* | |
* will yield: | |
* | |
* $keys_array = [ | |
* 'a' => [0, 2, 4], | |
* 'b' => [1, 3, 5] | |
* ]; | |
* | |
*/ | |
$keys_array = array(); | |
foreach ($list as $i => $item) { | |
foreach($keys as $k => $key) { | |
$keys_array[$key][$i] = $item[$key]; | |
// Since we're looping through our $keys, check for sort_order | |
if (!isset($keys_array[$key]['sort_order'])) { | |
// Use SORT_ASC if none are present | |
$keys_array[$key]['sort_order'] = ((isset($keys_order[$k]) && $keys_order[$k] === 'desc') ? SORT_DESC : SORT_ASC); | |
} | |
// And check for sort_flags | |
if (!isset($keys_array[$key]['sort_flags'])) { | |
// Use SORT_REGULAR if no value is present | |
switch ((isset($key_flags[$k]) ? $key_flags[$k] : 'regular')) { | |
case 'numeric': | |
$sort_flag = SORT_NUMERIC; | |
break; | |
case 'string': | |
$sort_flag = SORT_STRING; | |
break; | |
case 'locale_string': | |
$sort_flag = SORT_LOCALE_STRING; | |
break; | |
case 'natural': | |
$sort_flag = SORT_NATURAL; | |
break; | |
case 'flag_case': | |
$sort_flag = SORT_FLAG_CASE; | |
break; | |
case 'regular': | |
default: | |
$sort_flag = SORT_REGULAR; | |
break; | |
} | |
$keys_array[$key]['sort_flags'] = $sort_flag; | |
unset($sort_flag); | |
} | |
} | |
} | |
// Build list of arguments to be unpacked in our array_multisort call | |
$arg_array = array(); | |
foreach ($keys_array as $key_name => $arg) { | |
$sort_order = $arg['sort_order']; | |
unset($arg['sort_order']); | |
$sort_flag = $arg['sort_flags']; | |
unset($arg['sort_flags']); | |
$arg_array[] = $arg; | |
$arg_array[] = $sort_order; | |
$arg_array[] = $sort_flag; | |
} | |
$arg_array[] = &$list; | |
// Sort the columns and modify our $list in place | |
// Requires PHP 5.6 | |
return array_multisort(...$arg_array); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment