如何在 PHP 中对数组和数据进行排序? [英] How can I sort arrays and data in PHP?

查看:34
本文介绍了如何在 PHP 中对数组和数据进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

本题旨在作为 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.

如何在 PHP 中对数组进行排序?
如何在 PHP 中对 复杂 数组进行排序?
如何在 PHP 中对对象数组进行排序?

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. 基本的一维数组;包括多维数组,包括对象数组;包括根据另一个数组对一个数组进行排序

使用 SPL 排序

稳定排序

有关使用 PHP 现有函数的实际答案,请参见 1.,有关排序算法的学术详细答案(PHP 的函数实现了哪些函数以及您可能在非常非常复杂的情况下需要哪些函数),见2.

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.

推荐答案

基本一维数组

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

适用的排序函数:

  • 排序
  • rsort
  • 分类
  • arsort
  • natsort
  • natcasesort
  • ksort
  • krsort

它们之间的区别仅在于是否保留了键值关联(a"函数),是从低到高排序还是反向排序(r"),它是对值还是键进行排序(k")以及它如何比较值(nat"与正常).参见 http://php.net/manual/en/array.sorting.php 概述和更多详细信息的链接.

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.

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

如果您想按每个条目的键 'foo' 对 $array 进行排序,您需要一个自定义比较函数.上面的 sort 和相关函数处理简单的值,它们知道如何比较和排序.PHP 不只是简单地知道"但是如何处理复杂值,例如array('foo' => 'bar', 'baz' => 42);所以你需要告诉它.

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.

为此,您需要创建一个比较函数.该函数接受两个元素,如果这些元素被认为相等,则必须返回 0,如果第一个值小于 0,则返回值小于 0,而值大于 0 如果第一个值更高.这就是所需要的:

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;
    }
}

通常,您需要使用匿名函数作为回调.如果要使用方法或静态方法,请参阅指定回调的其他方式在 PHP 中.

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.

示例用法:

usort($array, 'cmp');

usort 将从数组中取出两个项目并用它们调用您的 cmp 函数.所以 cmp() 将使用 $a 作为 array('foo' => 'bar', 'baz' => 42)code> 和 $b 作为另一个 array('foo' => ..., 'baz' => ...).然后函数返回给 usort 哪个值更大或者它们是否相等.usort 重复这个过程,为 $a$b 传递不同的值,直到数组被排序.cmp 函数将被调用多次,至少$array 中的值一样多,$array 的值组合不同code>$a 和 $b 每次.

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.

请注意,数组是就地排序,您不需要将返回值分配给任何东西.$array = sort($array) 将用 true 替换数组,而不是用排序后的数组.只需 sort($array); 就可以了.

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.

如果你想按baz键排序,它是数字,你需要做的就是:

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'];
}

感谢数学的力量,这会返回一个值<0、0 或 >0 取决于 $a 是否小于、等于或大于 $b.

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.

请注意,这不适用于 float 值,因为它们将被简化为 int 并失去精度.改用显式的 -101 返回值.

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.

如果你有一个对象数组,它的工作方式是一样的:

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 在这里完全符合 cmp 的预期,它返回 -101.

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

PHP 7 引入了太空船运算符,它统一并简化了相等/更小/大于类型之间的比较:>

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'];
}

按多个字段排序

如果您想主要按 foo 排序,但如果 foo 对两个元素相等,则按 baz 排序:

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'];
    }
}

对于那些熟悉的人来说,这相当于一个带有 ORDER BY foo, baz 的 SQL 查询.
另请参阅这个非常简洁的速记版本如何为任意数量的键动态创建这样的比较函数.

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.

如果您想将元素排序为手动顺序"像foo"、bar"、baz":

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);
}


对于上述所有内容,如果您使用的是 PHP 5.3 或更高版本(并且您确实应该),请使用匿名函数来缩短代码并避免另一个全局函数四处浮动:


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']; });

这就是对复杂的多维数组进行排序的简单程度.再一次,想想教 PHP 如何判断两个项目中的哪一个更大";让 PHP 进行实际的排序.

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.

对于上述所有内容,要在升序和降序之间切换,只需交换 $a$b 参数.例如:

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

根据另一个数组对一个数组进行排序

然后是特殊的 array_multisort,它可以让你根据另一个:

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');

这里的预期结果是:

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

使用 array_multisort 到达那里:

array_multisort($array1, $array2);

从 PHP 5.5.0 开始,您可以使用 array_column 从多维数组中提取一列并在该列上对数组进行排序:

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);

您还可以在任一方向对多于一列进行排序:

You can also sort on more than one column each in either direction:

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

从 PHP 7.0.0 开始,您还可以从对象数组中提取属性.

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

如果您有更常见的情况,请随时编辑此答案.

这篇关于如何在 PHP 中对数组和数据进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆