Skip to content

Instantly share code, notes, and snippets.

@romellem
Last active April 29, 2016 13:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romellem/3cc96245671fc7ef63e84aa7d6dabb31 to your computer and use it in GitHub Desktop.
Save romellem/3cc96245671fc7ef63e84aa7d6dabb31 to your computer and use it in GitHub Desktop.
Helper function to Sort an array of objects by multiple keys.
<?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