基本一维数组
$array = array(3, 5, 2, 8);
适用的排序函数:
排序
函数
带点
arsort
的作用
natcasesort
ksort
作用
它们之间的区别仅仅在于是否保留键值关联(“a”函数),是从低到高排序还是反向排序(“r”),是对值排序还是对键排序(“k”),以及如何比较值(“nat”vs. normal)。有关概述和进一步细节的链接,请参阅http://php.net/manual/en/array.sorting.php。
多维数组,包括对象数组
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
如果你想根据每个条目的'foo'键对$array排序,你需要一个自定义比较函数。上面的排序和相关函数工作在简单的值上,它们知道如何比较和排序。PHP并不简单地“知道”如何处理复杂的值,例如数组('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
uasort
uksort
同样,它们的区别只在于是否保持键-值关联并按值或键排序。详细信息请阅读他们的文档。
使用示例:
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.
要习惯这个想法,试试这个:
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,而不是一个排序的数组。只是数组($);的工作原理。
自定义数值比较
如果你想按baz键排序,它是数字,你所需要做的就是:
function cmp(array $a, array $b) {
return $a['baz'] - $b['baz'];
}
感谢MATH的力量,这将返回一个< 0,0或> 0的值,取决于$a是否小于、等于或大于$b。
注意,这对于浮点值并不适用,因为它们将被简化为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引入了宇宙飞船操作符,它统一并简化了不同类型之间的相等/较小/较大比较:
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'];
}
}
对于那些熟悉的人来说,这相当于一个带有ORDER BY foo, baz的SQL查询。
还可以查看这个非常简洁的简写版本,以及如何为任意数量的键动态创建这样的比较函数。
按手动、静态顺序排序
如果你想将元素按“手动顺序”排序,比如“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);
你也可以对多个列进行排序:
array_multisort(array_column($array, 'foo'), SORT_DESC,
array_column($array, 'bar'), SORT_ASC,
$array);
从PHP 7.0.0开始,您还可以从对象数组中提取属性。
如果你有更多的常见情况,请随意编辑这个答案。