这个问题是关于PHP中数组排序问题的参考.很容易认为你的 case 是独特的,值得提出一个新问题,但大多数都是本页解决方案的一个小变化.

如果您的问题作为此问题的副本而关闭,请仅在您能够解释问题与以下所有问题明显不同的情况下才要求重新打开您的问题.

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. 一百

  2. 一百

  3. 一百

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

推荐答案

Basic one dimensional arrays

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

适用的分拣功能:

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

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

Multi dimensional arrays, including arrays of objects

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

如果你想按每个条目的"foo"键对$array进行排序,你需要custom comparison function.上述sort和相关函数处理简单的值,它们知道如何比较和排序.不过,PHP并不只是"知道"如何处理complex value,比如array('foo' => 'bar', 'baz' => 42);所以你需要说出来.

要做到这一点,你需要创建一个comparison function.该函数接受两个元素,如果认为这些元素相等,则必须返回0;如果第一个值较低,则返回小于0的值;如果第一个值较高,则返回大于0的值.这就是所需要的:

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

通常,您会希望使用anonymous function作为回调.如果要使用方法或静态方法,请参阅other ways of specifying a callback in PHP.

然后使用以下函数之一:

同样,它们的不同之处只在于它们是否保持键-值关联并按值或键排序.有关详细信息,请阅读他们的文档.

示例用法:

usort($array, 'cmp');

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

要习惯这个 idea ,请try 以下方法:

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

您所做的只是定义一种自定义方式来比较两个项目,这就是您所需要的.这适用于各种价值观.

顺便说一句,这对任何值都有效,值不必是复杂的array.如果要进行自定义比较,也可以对简单的数字数组进行比较.

sort sorts by reference and does not return anything useful!

请注意,数组对in place进行排序,您不需要将返回值分配给任何内容.$array = sort($array)会将数组替换为true,而不是排序的array.只有sort($array);个能用.

自定义数字比较

如果要按数字baz键进行排序,只需执行以下操作:

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

多亏了The PoWEr oF MATH,这将根据$a是小于、等于还是大于$b返回值<;0、0或>;0.

请注意,这对于float个值来说效果不好,因为它们将被减少到int并失go 精度.而是使用显式的-101返回值.

对象

如果有一个对象数组,其工作方式相同:

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

功能

您可以在比较函数中执行任何需要的操作,包括调用函数:

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

第一个字符串比较版本的快捷方式:

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

strcmpcmp的预期完全一样,它返回-101.

宇宙飞船操作员

PHP7引入了spaceship operator,它统一并简化了跨类型的相等/小于/大于比较:

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

按多个字段排序

如果您想主要按foo排序,但如果foo等于两个元素,则按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.

按手动、静态顺序排序

如果要将元素排序为类似"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或更高版本(而且您真的应该这么做),请使用匿名函数来编写更短的代码,并避免出现另一个全局函数:

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

这就是对复杂的多维数组进行排序的简单方式.同样,只考虑teaching PHP how to tell which of two items is "greater";让PHP进行实际排序.

同样,对于以上所有情况,要在升序和降序之间切换,只需交换$a$b参数即可.例如:

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

Sorting one array based on another

然后是特殊的array_multisort,它允许您根据一个数组对另一个数组进行排序:

$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从多维数组中提取一列,并对该列上的数组进行排序:

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

您还可以按两个方向对多个列进行排序:

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

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


如果你有更常见的情况,请随意编辑这个答案

Php相关问答推荐

如何在搜索域名时重定向到登陆页?

如何使用属性#[Embedded]嵌入带有规则的对象集合?

从产品中获取WooCommerce产品属性单选按钮的列表WP_Query

以编程方式更改新订单、已取消订单和失败订单的邮箱WooCommerce通知

照明\Support\Collection::Filter():参数#1($Callback)的类型必须为?可调用、已给定数组、已调用

Mysqli_stmt::Execute():结果字段元数据中存在过早的EOF

Laravel:测试命令时无法获取工作通知::AssertSentTo

在PHP中,如何将介于0和1之间(包括0和1)的浮点概率转换为数组索引?

使用PHP编码的字符串与使用OpenSSL编写的shell 代码之间的差异

使用ESI的Symfony Sulu清漆

按列值将二维数组排序为不超过N个的递增组

文件::Files()响应返回空对象数组

WordPress:今天的计数';修改和发布的帖子

WooCommerce产品页面上没有产品详细信息

单个产品页面 WooCommerce 订阅价格字符串的更改

Laravel Eloquent(where 子句)

php preg_match 验证 Tiktok 用户名

PHP preg_replace括号和方括号内的所有逗号

我怎样才能在 .htaccess 中有 2 个参数?

在全局安装 Composer 包后运行命令