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 精度.而是使用显式的-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
.
宇宙飞船操作员
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开始,您还可以从对象数组中提取属性.
如果你有更常见的情况,请随意编辑这个答案