Skip to content

Instantly share code, notes, and snippets.

@amnuts
Last active June 8, 2020 20:35
Show Gist options
  • Save amnuts/8633684 to your computer and use it in GitHub Desktop.
Save amnuts/8633684 to your computer and use it in GitHub Desktop.
Sort array of objects by one or more properties of the object.
<?php
/**
* Sort an array of objects.
*
* Requires PHP 5.3+ to be installed.
*
* Will use the Intl extension to normalize characters if it's
* available.
*
* You can pass in one or more properties on which to sort. If a
* string is supplied as the sole property, or if you specify a
* property without a sort order then the sorting will be ascending.
*
* If the key of an array is an array, then it will sorted down to that
* level of node.
*
* Example usages:
*
* osort($items, 'size');
* osort($items, ['size', ['time' => SORT_DESC, 'user' => SORT_ASC]]);
* osort($items, ['size', ['user', 'forname']])
*
* @param array $array
* @param string|array $properties
*/
function osort(&$array, $properties)
{
if (is_string($properties)) {
$properties = array($properties => SORT_ASC);
}
uasort($array, function($a, $b) use ($properties) {
foreach($properties as $k => $v) {
if (is_int($k)) {
$k = $v;
$v = SORT_ASC;
}
$collapse = function($node, $props) {
if (is_array($props)) {
foreach ($props as $prop) {
$node = (!isset($node->$prop)) ? null : $node->$prop;
}
return $node;
} else {
return (!isset($node->$props)) ? null : $node->$props;
}
};
if (class_exists('\Normalizer')) {
$aProp = \Normalizer::normalize($collapse($a, $k), \Normalizer::FORM_D);
$bProp = \Normalizer::normalize($collapse($b, $k), \Normalizer::FORM_D);
} else {
$aProp = $collapse($a, $k);
$bProp = $collapse($b, $k);
}
if ($aProp != $bProp) {
return ($v == SORT_ASC)
? strnatcasecmp($aProp, $bProp)
: strnatcasecmp($bProp, $aProp);
}
}
return 0;
});
}
@amnuts
Copy link
Author

amnuts commented Sep 16, 2017

@rodmar35 👍 Thanks for the feedback - corrected now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment