3v4l.org

run code in 300+ PHP versions simultaneously
<?php $orderList = [ 'Jake', 'Scully' => [ 'pet', 'friend' => [ 'Michael', 'Merissa', ], 'Norm', ], 'Amy', 'Charles', 'Hitchcock', ]; $items = [ [ 'name' => 'Scully', 'related' => [ [ 'name' => 'Norm', 'category' => 'self' ], [ 'name' => 'Earl', 'category' => 'friend' ], [ 'name' => 'Kelly', 'category' => 'pet' ], [ 'name' => 'Michael', 'category' => 'friend' ], [ 'name' => 'Merissa', 'category' => 'friend' ], ], ], [ 'name' => 'Rosa', 'related' => [], ], [ 'name' => 'Jake', 'related' => [ [ 'name' => 'Franzia', 'category' => 'nemesis' ], [ 'name' => 'Doug' ], ], ], [ 'name' => 'Hitchcock', 'related' => [], ], [ 'name' => 'Amy', 'related' => [], ], ]; function getTopLevelItemsFromMixedList(array $mixedList): array { $topLevels = []; foreach ($mixedList as $item => $value) { $topLevels[] = is_int($item) ? $value : $item; } return $topLevels; } function sort_by(array $array, callable $sortKeyResolver, ...$sortArgs) { $mapped = array_map($sortKeyResolver, $array); asort($mapped, ...$sortArgs); $sorted = []; foreach ($mapped as $key => $index) { $sorted[] = $array[$key]; } return $sorted; } $topLevelOrder = getTopLevelItemsFromMixedList($orderList); $sortKeyResolver = function ($item) use ($topLevelOrder) { $orderListIndex = array_search($item['name'], $topLevelOrder); return $orderListIndex === false ? count($topLevelOrder).$item['name'] : $orderListIndex; }; // First, sort parents $items = sort_by($items, $sortKeyResolver, SORT_NATURAL); // Then sort children foreach ($items as &$item) { $children = $item['related'] ?? []; if(empty($orderList[$item['name']])) { // No order was specified for the children, so just sort them as normal $item['related'] = sort_by($children, fn ($child) => $child['name'], SORT_NATURAL); continue; } // An order was specified; it can contain children names or categories, // so let'sjust call it the "Level 2" order (L2). $l2Order = getTopLevelItemsFromMixedList($orderList[$item['name']]); $sortKeyResolver = function ($childItem) use ($l2Order) { // First, we check if there's an entry for the item's name $indexOfChildInL2Order = array_search($childItem['name'], $l2Order); if ($indexOfChildInL2Order !== false) { return $indexOfChildInL2Order; } // Check if there's an entry for the item's category $indexOfCategoryInL2Order = array_search($childItem['category'], $l2Order); if ($indexOfCategoryInL2Order !== false) { // There's an entry for the category! // Now check if there's an entry for the item within the category. $orderOfChildrenInCategory = $l2Order[$childItem['category']] ?? []; $indexOfChildInCategory = array_search($childItem['name'], $orderOfChildrenInCategory); return $indexOfChildInCategory === false ? $indexOfCategoryInL2Order.$childItem['name'] : ($indexOfCategoryInL2Order + ($indexOfChildInCategory * 0.1)); } return count($l2Order).$childItem['name']; }; $item['related'] = sort_by($children, $sortKeyResolver, SORT_NATURAL); } print_r($items);

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.1.100.0050.00417.48

preferences:
26.53 ms | 406 KiB | 6 Q