app/Fact.php
public static function sortFacts(Collection $unsorted): Collection
    {
        $dated    = [];
        $nondated = [];
        $sorted   = [];

        // Split the array into dated and non-dated arrays
        $order = 0;

        foreach ($unsorted as $fact) {
            $fact->sortOrder = $order;
            $order++;

            if ($fact->date()->isOK()) {
                $dated[] = $fact;
            } else {
                $nondated[] = $fact;
            }
        }

        usort($dated, self::dateComparator());
        usort($nondated, self::typeComparator());

        // Merge the arrays
        $dc = count($dated);
        $nc = count($nondated);
        $i  = 0;
        $j  = 0;

        // while there is anything in the dated array continue merging
        while ($i < $dc) {
            // compare each fact by type to merge them in order
            if ($j < $nc && self::typeComparator()($dated[$i], $nondated[$j]) > 0) {
                $sorted[] = $nondated[$j];
                $j++;
            } else {
                $sorted[] = $dated[$i];
                $i++;
            }
        }

        // get anything that might be left in the nondated array
        while ($j < $nc) {
            $sorted[] = $nondated[$j];
            $j++;
        }

        return new Collection($sorted);
    }
public static function sortFacts(Collection $unsorted): Collection
    {
        $dated    = [];
        $nondated = [];
        $sorted   = [];

        // Split the array into dated and non-dated arrays
        $order = 0;

        foreach ($unsorted as $fact) {
            $fact->sortOrder = $order;
            $order++;

            if ($fact->date()->isOK()) {
                $dated[] = $fact;
            } else {
                $nondated[] = $fact;
            }
        }

        usort($dated, self::dateComparator());
        usort($nondated, self::typeComparator());

        // Merge the arrays
        $dc = count($dated);
        $nc = count($nondated);
        $i  = 0;
        $j  = 0;

        // while there is anything in the dated array continue merging
        while ($i < $dc) {
            // compare each fact by type to merge them in order
            if ($j < $nc && self::typeComparator()($dated[$i], $nondated[$j]) > 0) {
                $sorted[] = $nondated[$j];
                $j++;
            } else {
                $sorted[] = $dated[$i];
                $i++;
            }
        }

        // get anything that might be left in the nondated array
        while ($j < $nc) {
            $sorted[] = $nondated[$j];
            $j++;
        }

        return new Collection($sorted);
    }
public static function sortFacts ( Collection $ unsorted ) : Collection { $ dated = [ ] ; $ nondated = [ ] ; $ sorted = [ ] ; // Split the array into dated and non-dated arrays $ order = 0 ; foreach ( $ unsorted as $ fact ) { $ fact -> sortOrder = $ order ; $ order ++ ; if ( $ fact -> date ( ) -> isOK ( ) ) { $ dated [ ] = $ fact ; } else { $ nondated [ ] = $ fact ; } } usort ( $ dated , self :: dateComparator ( ) ) ; usort ( $ nondated , self :: typeComparator ( ) ) ; // Merge the arrays $ dc = count ( $ dated ) ; $ nc = count ( $ nondated ) ; $ i = 0 ; $ j = 0 ; // while there is anything in the dated array continue merging while ( $ i < $ dc ) { // compare each fact by type to merge them in order if ( $ j < $ nc && self :: typeComparator ( ) ( $ dated [ $ i ] , $ nondated [ $ j ] ) > 0 ) { $ sorted [ ] = $ nondated [ $ j ] ; $ j ++ ; } else { $ sorted [ ] = $ dated [ $ i ] ; $ i ++ ; } } // get anything that might be left in the nondated array while ( $ j < $ nc ) { $ sorted [ ] = $ nondated [ $ j ] ; $ j ++ ; } return new Collection ( $ sorted ) ; }
A multi-key sort
1. First divide the facts into two arrays one set with dates and one set without dates
2. Sort each of the two new arrays, the date using the compare date function, the non-dated
using the compare type function
3. Then merge the arrays back into the original array using the compare type function

@param Collection $unsorted

@return Collection
@return Fact[]
A multi - key sort 1 . First divide the facts into two arrays one set with dates and one set without dates 2 . Sort each of the two new arrays the date using the compare date function the non - dated using the compare type function 3 . Then merge the arrays back into the original array using the compare type function