Home  >  Q&A  >  body text

How to sort arrays and data in PHP?

This question is intended as a reference regarding array sorting issues in PHP. It's easy to think that your particular case is unique and deserves a new question, but most are actually just minor variations on one of the solutions on this page.

If your question was closed as a duplicate of this question, please only ask to reopen your question if you can explain why it is significantly different from all of the following questions.

How to sort an array in PHP?

How to sort a complex array in PHP?

How to sort an array of objects in PHP?


  1. Basic one-dimensional array; included. Multidimensional arrays, incl. Array of objects; includes. Sort one array based on another array

  2. Use SPL sorting

  3. Stable sorting

See 1. for a practical answer using PHP's existing functions, for an academically detailed answer about sorting algorithms (that PHP functions implement and that you might need in very, very complex situations), See 2.

P粉068174996P粉068174996338 days ago550

reply all(2)I'll reply

  • P粉476475551

    P粉4764755512023-10-18 13:03:18

    Okay, deceze has most of the basic methods covered, I will try to look at other types of sorting

    Use SPL sorting

    SplHeap

    class SimpleHeapSort extends SplHeap {
        public function compare($a, $b) {
            return strcmp($a, $b);
        }
    }
    
    // Let's populate our heap here (data of 2009)
    $heap = new SimpleHeapSort();
    $heap->insert("a");
    $heap->insert("b");
    $heap->insert("c");
    
    echo implode(PHP_EOL, iterator_to_array($heap));

    Output

    c
    b
    a

    SplMaxHeap

    The SplMaxHeap class provides the main functionality of the heap, keeping the maximum value at the top.

    $heap = new SplMaxHeap();
    $heap->insert(1);
    $heap->insert(2);
    $heap->insert(3);

    SplMinHeap

    $heap = new SplMinHeap ();
    $heap->insert(3);
    $heap->insert(1);
    $heap->insert(2);

    Other types of sorting

    Bubble Sort

    Excerpted from Wikipedia article about bubble sort:

    function bubbleSort(array $array) {
        $array_size = count($array);
        for($i = 0; $i < $array_size; $i ++) {
            for($j = 0; $j < $array_size; $j ++) {
                if ($array[$i] < $array[$j]) {
                    $tem = $array[$i];
                    $array[$i] = $array[$j];
                    $array[$j] = $tem;
                }
            }
        }
        return $array;
    }

    Select sort

    Excerpted from Wikipedia article on selection sort:

    function selectionSort(array $array) {
        $length = count($array);
        for($i = 0; $i < $length; $i ++) {
            $min = $i;
            for($j = $i + 1; $j < $length; $j ++) {
                if ($array[$j] < $array[$min]) {
                    $min = $j;
                }
            }
            $tmp = $array[$min];
            $array[$min] = $array[$i];
            $array[$i] = $tmp;
        }
        return $array;
    }

    Insertion sort

    Excerpted from Wikipedia article about insertion sort:

    function insertionSort(array $array) {
        $count = count($array);
        for($i = 1; $i < $count; $i ++) {
    
            $j = $i - 1;
            // second element of the array
            $element = $array[$i];
            while ( $j >= 0 && $array[$j] > $element ) {
                $array[$j + 1] = $array[$j];
                $array[$j] = $element;
                $j = $j - 1;
            }
        }
        return $array;
    }

    Hill sort

    Excerpted from Wikipedia article about Shellsort:

    function shellSort(array $array) {
        $gaps = array(
                1,
                2,
                3,
                4,
                6
        );
        $gap = array_pop($gaps);
        $length = count($array);
        while ( $gap > 0 ) {
            for($i = $gap; $i < $length; $i ++) {
                $tmp = $array[$i];
                $j = $i;
                while ( $j >= $gap && $array[$j - $gap] > $tmp ) {
                    $array[$j] = $array[$j - $gap];
                    $j -= $gap;
                }
                $array[$j] = $tmp;
            }
            $gap = array_pop($gaps);
        }
        return $array;
    }

    comb sorting

    Excerpted from Wikipedia article on comb sort:

    function combSort(array $array) {
        $gap = count($array);
        $swap = true;
        while ( $gap > 1 || $swap ) {
            if ($gap > 1)
                $gap /= 1.25;
            $swap = false;
            $i = 0;
            while ( $i + $gap < count($array) ) {
                if ($array[$i] > $array[$i + $gap]) {
                    // swapping the elements.
                    list($array[$i], $array[$i + $gap]) = array(
                            $array[$i + $gap],
                            $array[$i]
                    );
                    $swap = true;
                }
                $i ++;
            }
        }
        return $array;
    }

    Merge sort

    From Wikipedia article about merge sort:

    function mergeSort(array $array) {
        if (count($array) <= 1)
            return $array;
    
        $left = mergeSort(array_splice($array, floor(count($array) / 2)));
        $right = mergeSort($array);
    
        $result = array();
    
        while ( count($left) > 0 && count($right) > 0 ) {
            if ($left[0] <= $right[0]) {
                array_push($result, array_shift($left));
            } else {
                array_push($result, array_shift($right));
            }
        }
        while ( count($left) > 0 )
            array_push($result, array_shift($left));
    
        while ( count($right) > 0 )
            array_push($result, array_shift($right));
    
        return $result;
    }

    Quick sort

    Excerpted from Wikipedia article about quick sort:

    function quickSort(array $array) {
        if (count($array) == 0) {
            return $array;
        }
        $pivot = $array[0];
        $left = $right = array();
        for($i = 1; $i < count($array); $i ++) {
            if ($array[$i] < $pivot) {
                $left[] = $array[$i];
            } else {
                $right[] = $array[$i];
            }
        }
        return array_merge(quickSort($left), array(
                $pivot
        ), quickSort($right));
    }

    Arrange sorting

    Excerpted from Wikipedia article about sorting:

    function permutationSort($items, $perms = array()) {
        if (empty($items)) {
            if (inOrder($perms)) {
                return $perms;
            }
        } else {
            for($i = count($items) - 1; $i >= 0; -- $i) {
                $newitems = $items;
                $newperms = $perms;
                list($foo) = array_splice($newitems, $i, 1);
                array_unshift($newperms, $foo);
                $res = permutationSort($newitems, $newperms);
                if ($res) {
                    return $res;
                }
            }
        }
    }
    
    function inOrder($array) {
        for($i = 0; $i < count($array); $i ++) {
            if (isset($array[$i + 1])) {
                if ($array[$i] > $array[$i + 1]) {
                    return False;
                }
            }
        }
        return True;
    }

    Radix sort

    Excerpted from Wikipedia article on radix sort:

    // Radix Sort for 0 to 256
    function radixSort($array) {
        $n = count($array);
        $partition = array();
    
        for($slot = 0; $slot < 256; ++ $slot) {
            $partition[] = array();
        }
    
        for($i = 0; $i < $n; ++ $i) {
            $partition[$array[$i]->age & 0xFF][] = &$array[$i];
        }
    
        $i = 0;
    
        for($slot = 0; $slot < 256; ++ $slot) {
            for($j = 0, $n = count($partition[$slot]); $j < $n; ++ $j) {
                $array[$i ++] = &$partition[$slot][$j];
            }
        }
        return $array;
    }

    reply
    0
  • P粉952365143

    P粉9523651432023-10-18 09:01:08

    Basic one-dimensional array

    $array = array(3, 5, 2, 8);

    Applicable sorting functions:

    • Sort
    • Sort
    • Classification
    • Sort
    • natsort
    • natcasesort
    • ksort
    • krsort

    The only difference between them is whether to preserve the key-value association ("a" function), whether to sort from low to high or in reverse order ("r" >" ), whether to sort values ​​or keys ("k") and how to compare values ​​("nat" vs. normal). See http://php.net /manual/en/array.sorting.php Link to get an overview and more details.

    Multidimensional arrays, including object arrays

    $array = array(
        array('foo' => 'bar', 'baz' => 42),
        array('foo' => ...,   'baz' => ...),
        ...
    );

    If you want to sort the $array by the key "foo" for each entry, you will need a custom comparison function . The sort above and related functions work well for simple values ​​that they know how to compare and sort. PHP doesn't simply "know" what to do with complex values like array('foo' => 'bar', 'baz' => 42); so you need to tell it.

    To do this, you need to create a comparison function. This function accepts two elements and must return 0 if the elements are considered equal; if the first value is lower, it must return a value lower than 0; if the first value is considered equal A value below 0 must return a value above 0 if the first value is higher. This is what is needed:

    function cmp(array $a, array $b) {
        if ($a['foo'] < $b['foo']) {
            return -1;
        } else if ($a['foo'] > $b['foo']) {
            return 1;
        } else {
            return 0;
        }
    }

    Typically, you need to use an anonymous function as a callback. If you want to use methods or static methods, see Other Ways to Specify Callbacks in PHP.

    You can then use one of the following functions:

    Again, they only differ in whether key-value associations are preserved and whether they are sorted by value or key. Please read their documentation for details.

    Usage example:

    usort($array, 'cmp');

    usort will take two items from the array and call your cmp function with them. So cmp() will call array('foo' => 'bar', 'baz' => 42) and in the form $a $b as another array('foo' => ..., 'baz' => ...). The function then returns usort which value is greater or if they are equal. usort Repeat this process, passing different values ​​for $a and $b, until the array is sorted. cmp The function will be called multiple times, at least as many values ​​as there are in $array, and different combinations of values ​​each time code >$a and $b.

    To get used to this idea, try the following:

    function cmp($a, $b) {
        echo 'cmp called with $a:', PHP_EOL;
        var_dump($a);
        echo 'and $b:', PHP_EOL;
        var_dump($b);
    }

    All you do is define a custom way to compare two items and that's all you need. This works for a variety of values.

    BTW, this works with any values, which don't have to be complex arrays. You can also compare simple arrays of numbers if you want to do a custom comparison.

    sort Sorting by reference will not return anything useful!

    Note that arrays are sorted in-place, you do not need to assign the return value to anything. $array = sort($array) will replace the array with true, not the sorted array. Just sort($array);.

    Custom number comparison

    If you want to sort by the numeric keys baz, all you need to do is:

    function cmp(array $a, array $b) {
        return $a['baz'] - $b['baz'];
    }

    Thanks to the power of math , this will return a value < 0、0 或 > 0 depending on whether $a is less than, equal to, or greater than $b.

    Note that this will not work for float values, as they will be simplified to int and lose precision. Please use explicit -1, 0, and 1 return values ​​instead.

    Object

    If you have an array of objects, it works the same way:

    function cmp($a, $b) {
        return $a->baz - $b->baz;
    }

    function

    You can do anything you need in the comparison function, including calling functions:

    function cmp(array $a, array $b) {
        return someFunction($a['baz']) - someFunction($b['baz']);
    }

    String

    Shortcut for the first string comparison version:

    function cmp(array $a, array $b) {
        return strcmp($a['foo'], $b['foo']);
    }

    strcmp does exactly what is expected from cmp, which returns -1, 0, or 1.

    Spaceship Operator

    PHP 7 introduces the spaceship operator, which unifies and simplifies equal/less than/greater than comparisons across types:

    function cmp(array $a, array $b) {
        return $a['foo'] <=> $b['foo'];
    }

    Sort by multiple fields

    If you want to sort primarily by foo, but if two elements' foo are equal, then sort by baz:

    function cmp(array $a, array $b) {
        if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
            return $cmp;
        } else {
            return $a['baz'] - $b['baz'];
        }
    }

    For those familiar, this is equivalent to a SQL query using ORDER BY foo, baz.
    See also this very concise shorthand version and how to dynamically create such a comparison function for any number of keys .

    Sort by manual static order

    If you want to sort the elements into "manual order", e.g. "foo", "bar", "baz" :

    function cmp(array $a, array $b) {
        static $order = array('foo', 'bar', 'baz');
        return array_search($a['foo'], $order) - array_search($b['foo'], $order);
    }

    As with all of the above, if you're using PHP 5.3 or higher (and you really should be), use anonymous functions to shorten your code and avoid another global function:

    usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });

    This is a simple way to sort complex multi-dimensional arrays. Again, teach PHP how to determine which of two items is "bigger"; let PHP do the actual sorting.

    Additionally, for all of the above, to switch between ascending and descending order, just swap the $a and $b parameters. For example:

    return $a['baz'] - $b['baz']; // ascending
    return $b['baz'] - $a['baz']; // descending

    Sort an array based on another array

    There is also a peculiar array_multisort, which allows you to sort an array based on: Another:

    $array1 = array( 4,   6,   1);
    $array2 = array('a', 'b', 'c');

    The expected result here is:

    $array2 = array('c', 'a', 'b');  // the sorted order of $array1

    Get there using array_multisort:

    array_multisort($array1, $array2);

    Starting with PHP 5.5.0, you can use array_column to extract a column from a multidimensional array and sort the array on that column:

    array_multisort(array_column($array, 'foo'), SORT_DESC, $array);

    You can also sort multiple columns in either direction:

    array_multisort(array_column($array, 'foo'), SORT_DESC,
                    array_column($array, 'bar'), SORT_ASC,
                    $array);

    Starting with PHP 7.0.0, you can also extract properties from an array of objects.


    reply
    0
  • Cancelreply