基本的一维数组
$array = array(3, 5, 2, 8);
适用的排序功能:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
两者之间的区别仅在于是否保留键值关联(“ a
”功能),是否从低到高或反向r
排序(“ ”),对值或键进行排序(“ k
”)以及如何比较值(“ nat
”与正常)。有关概述以及指向更多详细信息的链接,请参见http://php.net/manual/zh-CN/array.sorting.php。
多维数组,包括对象数组
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
如果要按$array
每个条目的键'foo' 进行排序,则需要一个自定义比较函数。上面sort
和相关的函数使用它们知道如何比较和排序的简单值。PHP不会简单地“知道”如何处理复杂的值,例如array('foo' => 'bar', 'baz' => 42)
;所以你需要告诉它。
为此,您需要创建一个比较函数。该函数包含两个元素,并且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;
}
}
通常,您将需要使用匿名函数作为回调。如果要使用方法或静态方法,请参见在PHP中指定回调的其他方法。
然后,您可以使用以下功能之一:
同样,它们只是在保留键值关联以及按值或键排序方面有所不同。阅读他们的文档以了解详细信息。
用法示例:
usort($array, 'cmp');
usort
将从数组中取出两个项目,并cmp
使用它们来调用函数。因此cmp()
将被称为$a
as array('foo' => 'bar', 'baz' => 42)
和$b
as as array('foo' => ..., 'baz' => ...)
。然后,函数返回到usort
哪个值较大或它们是否相等。usort
重复此过程,为传递不同的值$a
,$b
直到对数组排序为止。该cmp
函数将被调用很多次,至少多次,有价值观$array
,与值的不同组合$a
和$b
每一次。
要习惯这个想法,请尝试以下操作:
function cmp($a, $b) {
echo 'cmp called with $a:', PHP_EOL;
var_dump($a);
echo 'and $b:', PHP_EOL;
var_dump($b);
}
您要做的就是定义一种自定义方式来比较两个项目,这就是您所需要的。这适用于各种价值。
顺便说一下,这适用于任何值,这些值不必是复杂的数组。如果您要进行自定义比较,则也可以对简单的数字数组进行比较。
sort
按引用排序,不返回任何有用的信息!
请注意,数组在适当的位置排序,您无需将返回值分配给任何对象。$array = sort($array)
将用替换数组true
,而不用排序后的数组。只是sort($array);
作品。
自定义数值比较
如果要按baz
数字键排序,则需要做的是:
function cmp(array $a, array $b) {
return $a['baz'] - $b['baz'];
}
多亏了数学运算的功率,它返回的值$a
小于,等于0还是大于0,具体取决于是小于,等于还是大于$b
。
请注意,这不适用于float
值,因为它们会降低为int
并失去精度。使用显式-1
,0
并1
返回值。
对象
如果您有一个对象数组,则其工作方式相同:
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']);
}
strcmp
不正是要的是什么的cmp
在这里,它返回-1
,0
或1
。
飞船操作员
PHP 7引入了spaceship运算符,该运算符统一并简化了与跨类型比较相比相等/较小/较大的操作:
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'];
}
}
对于熟悉的人,这等效于带有的SQL查询ORDER BY foo, baz
。
另请参阅此非常简洁的速记版本,以及如何为任意数量的键动态创建这样的比较函数。
排序为手动的静态订单
如果要将元素按“手动顺序”排序,例如“ 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']; });
这就是对复杂的多维数组进行排序的简单方式。再说一遍,只需要考虑教PHP如何分辨两个项目中的哪个“更大”即可;让PHP进行实际排序。
同样,对于以上所有内容,要在升序和降序之间切换,只需交换$a
和$b
参数即可。例如:
return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending
根据另一个对一个数组进行排序
然后是奇特的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);
从PHP 7.0.0开始,您还可以从对象数组中提取属性。
如果您遇到更常见的情况,请随时编辑此答案。