douji8017
2013-06-28 11:53
浏览 49
已采纳

如何在PHP中对数组和数据进行排序?

This question is intended as a reference for questions about sorting arrays in PHP. It is easy to think that your particular case is unique and worthy of a new question, but most are actually minor variations of one of the solutions on this page.

If your question is closed as a duplicate of this one, please ask for your question to be reopened only if you can explain why it differs markedly from all of the below.

How do I sort an array in PHP?
How do I sort a complex array in PHP?
How do I sort an array of objects in PHP?


  1. Basic one-dimensional arrays; Incl. Multidimensional arrays, incl. arrays of objects; Incl. Sorting one array based on another

  2. Sorting with SPL

  3. Stable sort

For the practical answer using PHP's existing functions see 1., for the academic in-detail answer on sorting algorithms (which PHP's functions implement and which you may need for really, really complex cases), see 2.

图片转代码服务由CSDN问答提供 功能建议

此问题旨在作为有关在PHP中排序数组的问题的参考。 很容易认为你的特定情况是独一无二的,值得一个新的问题,但大多数都是本页面上其中一个解决方案的微小变化。

如果你的问题被关闭了 这其中的一个副本,请询问您的问题只能重新打开,如果你能解释为什么所有的以下明显不同。

我如何排序 PHP中的数组?
如何在PHP中对复杂数组进行排序?
如何在PHP中对对象数组进行排序? < hr>

  1. 基本的一维数组; 含。 多维数组,包括 对象数组; 含。 基于另一个排列一个数组

  2. 使用SPL排序< / a>

  3. 稳定排序

    对于使用PHP现有函数的实际答案,请参阅1.,有关排序算法的学术详细答案(PHP的函数实现以及您可能 需要非常非常复杂的案例),见2。

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

10条回答 默认 最新

  • dpw50696 2013-06-28 11:53
    已采纳

    Basic one dimensional arrays

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

    Applicable sort functions:

    • sort
    • rsort
    • asort
    • arsort
    • natsort
    • natcasesort
    • ksort
    • krsort

    The difference between those is merely whether key-value associations are kept (the "a" functions), whether it sorts low-to-high or reverse ("r"), whether it sorts values or keys ("k") and how it compares values ("nat" vs. normal). See http://php.net/manual/en/array.sorting.php for an overview and links to further details.

    Multi dimensional arrays, including arrays of objects

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

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

    To do that, you need to create a comparison function. That function takes two elements and must return 0 if these elements are considered equal, a value lower than 0 if the first value is lower and a value higher than 0 if the first value is higher. That's all that's 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;
        }
    }
    

    Often, you will want to use an anonymous function as the callback. If you want to use a method or static method, see the other ways of specifying a callback in PHP.

    You then use one of these functions:

    Again, they only differ in whether they keep key-value associations and sort by values or keys. Read their documentation for details.

    Example usage:

    usort($array, 'cmp');
    

    usort will take two items from the array and call your cmp function with them. So cmp() will be called with $a as array('foo' => 'bar', 'baz' => 42) and $b as another array('foo' => ..., 'baz' => ...). The function then returns to usort which of the values was larger or whether they were equal. usort repeats this process passing different values for $a and $b until the array is sorted. The cmp function will be called many times, at least as many times as there are values in $array, with different combinations of values for $a and $b every time.

    To get used to this idea, try this:

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

    All you did was define a custom way to compare two items, that's all you need. That works with all sorts of values.

    By the way, this works on any value, the values don't have to be complex arrays. If you have a custom comparison you want to do, you can do it on a simple array of numbers too.

    sort sorts by reference and does not return anything useful!

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

    Custom numeric comparisons

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

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

    Thanks to The PoWEr oF MATH this returns a value < 0, 0 or > 0 depending on whether $a is lower than, equal to or larger than $b.

    Note that this won't work well for float values, since they'll be reduced to an int and lose precision. Use explicit -1, 0 and 1 return values instead.

    Objects

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

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

    Functions

    You can do anything you need inside a comparison function, including calling functions:

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

    Strings

    A shortcut for the first string comparison version:

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

    strcmp does exactly what's expected of cmp here, it returns -1, 0 or 1.

    Spaceship operator

    PHP 7 introduced the spaceship operator, which unifies and simplifies equal/smaller/larger than comparisons across types:

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

    Sorting by multiple fields

    If you want to sort primarily by foo, but if foo is equal for two elements 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 an SQL query with ORDER BY foo, baz.
    Also see this very neat shorthand version and how to create such a comparison function dynamically for an arbitrary number of keys.

    Sorting into a manual, static order

    If you want to sort elements into a "manual order" like "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);
    }
    

    For all the above, if you're using PHP 5.3 or higher (and you really should), use anonymous functions for shorter code and to avoid having another global function floating around:

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

    That's how simple sorting a complex multi-dimensional array can be. Again, just think in terms of teaching PHP how to tell which of two items is "greater"; let PHP do the actual sorting.

    Also for all of the above, to switch between ascending and descending order simply swap the $a and $b arguments around. E.g.:

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

    Sorting one array based on another

    And then there's the peculiar array_multisort, which lets you sort one array based on another:

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

    The expected result here would be:

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

    Use array_multisort to get there:

    array_multisort($array1, $array2);
    

    As of PHP 5.5.0 you can use array_column to extract a column from a multi dimensional array and sort the array on that column:

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

    As of PHP 7.0.0 you can also extract properties from an array of objects.


    If you have more common cases, feel free to edit this answer.

    评论
    解决 无用
    打赏 举报
查看更多回答(9条)

相关推荐 更多相似问题