<?php
$orderList = [
'Jake',
'Scully' => [
'pet',
'friend' => [
'Michael',
'Merissa',
],
'Norm',
],
'Amy',
'Charles',
'Hitchcock',
];
$items = [
[
'name' => 'Scully',
],
[
'name' => 'Rosa',
],
[
'name' => 'Bill',
],
[
'name' => 'Jake',
],
[
'name' => 'Hitchcock',
],
[
'name' => 'Amy',
],
];
function getTopLevelItemsFromMixedList(array $mixedList): array {
$topLevels = [];
foreach ($mixedList as $item => $value) {
$topLevels[] = is_int($item) ? $value : $item;
}
return $topLevels;
}
function getComparator(array $order): callable {
return function ($a, $b) use ($order) {
$indexOfA = array_search($a['name'], $order);
$indexOfB = array_search($b['name'], $order);
// If both are in the $order list, compare them based on their position in the list
if ($indexOfA !== false && $indexOfB !== false) {
return $indexOfA <=> $indexOfB;
}
// If only A is in the $order list, then it must come before B.
if ($indexOfA !== false) {
return -1;
}
// If only B is in the $order list, then it must come before A.
if ($indexOfB !== false) {
return 1;
}
// If neither is present, fall back to natural sort
return strnatcmp($a['name'], $b['name']);
};
}
$topLevelOrder = getTopLevelItemsFromMixedList($orderList);
usort($items, getComparator($topLevelOrder));
print_r($items);