基本一维数组
$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 http://php.net/manual/en/array.sorting.php以获得概述和更多详细信息的链接。
多维数组,包括对象数组
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
如果你想排序$array
通过每个条目的键“foo”,您需要一个自定义比较功能。以上sort
相关函数处理简单的值,它们知道如何比较和排序。 PHP 并不只是“知道”如何处理复数值 like 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;
}
}
通常,您会想要使用匿名函数 http://php.net/manual/en/functions.anonymous.php作为回调。如果您想使用方法或静态方法,请参阅在 PHP 中指定回调的其他方法 http://php.net/manual/en/language.types.callable.php.
然后您可以使用以下函数之一:
- usort http://php.net/usort
- uasort http://php.net/uasort
- uksort http://php.net/uksort
同样,它们的区别仅在于是否保留键值关联并按值或键排序。阅读他们的文档了解详细信息。
用法示例:
usort($array, 'cmp');
usort
将从数组中取出两项并调用您的cmp
与他们一起运作。所以cmp()
将被调用$a
as array('foo' => 'bar', 'baz' => 42)
and $b
作为另一个array('foo' => ..., 'baz' => ...)
。然后函数返回到usort
哪个值更大或者它们是否相等。usort
重复此过程,传递不同的值$a
and $b
直到数组排序完毕。这cmp
函数会被调用多次,at least中的值有多少次$array
,具有不同的值组合$a
and $b
每次。
要习惯这个想法,请尝试以下操作:
function cmp($a, $b) {
echo 'cmp called with $a:', PHP_EOL;
var_dump($a);
echo 'and $b:', PHP_EOL;
var_dump($b);
}
您所做的只是定义一种自定义方式来比较两个项目,这就是您所需要的。这适用于各种价值观。
顺便说一句,这适用于任何值,这些值不必是复杂的数组。如果您想要进行自定义比较,也可以对简单的数字数组进行比较。
sort
按引用排序并且不返回任何有用的内容!
注意数组是排序的in place,您不需要将返回值分配给任何东西。$array = sort($array)
将替换数组为true
,而不是排序数组。只是sort($array);
works.
自定义数字比较
如果你想按baz
key,它是数字,你需要做的就是:
function cmp(array $a, array $b) {
return $a['baz'] - $b['baz'];
}
谢谢数学的力量这将返回一个值 0,具体取决于是否$a
低于、等于或大于$b
.
请注意,这不适用于float
值,因为它们将减少到int
并失去精度。使用显式-1
, 0
and 1
相反,返回值。
Objects
如果你有一个对象数组,它的工作方式是相同的:
function cmp($a, $b) {
return $a->baz - $b->baz;
}
功能
您可以在比较函数中执行任何您需要的操作,包括调用函数:
function cmp(array $a, array $b) {
return someFunction($a['baz']) - someFunction($b['baz']);
}
Strings
第一个字符串比较版本的快捷方式:
function cmp(array $a, array $b) {
return strcmp($a['foo'], $b['foo']);
}
strcmp
完全符合预期cmp
在这里,它返回-1
, 0
or 1
.
宇宙飞船操作员
PHP 7 引入了宇宙飞船操作员 https://stackoverflow.com/a/31298778/476,它统一并简化了跨类型的等于/小于/大于比较:
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
.
另请参阅这个非常简洁的速记版本 https://stackoverflow.com/a/22812695/476 and 如何为任意数量的键动态创建这样的比较函数 https://stackoverflow.com/a/22829326/476.
排序为手动静态顺序
如果您想将元素排序为“手动顺序”,例如“富”、“酒吧”、“巴兹”:
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
and $b
周围的争论。例如。:
return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending
根据一个数组对另一个数组进行排序
然后就是奇特的地方array_multisort http://php.net/array_multisort,它允许您根据一个数组对另一个数组进行排序:
$array1 = array( 4, 6, 1);
$array2 = array('a', 'b', 'c');
这里的预期结果是:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
Use 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);
从 PHP 7.0.0 开始,您还可以从对象数组中提取属性。
If you have more common cases, feel free to edit this answer.