在PHP中,数组是个非常重要的数据类型,加上PHP的若类型特点,可以让我们肆无忌惮地往数组中添加任何对象,以至于经常变成多维数组。但能直接对多维数组进行处理的系统函数又特别少,所以就需要我们自定义处理函数。
因为工作中要用到多维数组的排序,所以今天特意研究了一下,这里整理出来,与大家学习共勉。
在PHP手册中,我们能找到usort()这个用户自定义排序函数:
<?php
$goods = array(
'0' => array(
'name'=>'apple',
'price'=>'2',
),
'1' => array(
'name'=>'grape',
'price'=>'1',
),
'2' => array(
'name'=>'lemon',
'price'=>'5',
),
);
function compare($a,$b){
if ($a['price'] == $b['price']) {
return 0;
}
return ($a['price'] > $b['price']) ? -1 : 1;
}
usort($goods,"compare");
print_r($goods);
?>
输出结果如下:
Array
(
[0] => Array
(
[name] => grape
[price] => 1
)
[1] => Array
(
[name] => apple
[price] => 2
)
[2] => Array
(
[name] => lemon
[price] => 5
)
)
如果我们要把它封装成函数可以做成这样
function sort_by_price(&$goods){
function compare($a,$b){
if ($a['price'] == $b['price']) {
return 0;
}
return ($a['price'] < $b['price']) ? -1 : 1;
}
usort($goods,"compare");
}
sort_by_price($goods);
但这样只能排序单一属性,如果想让排序指定属性,需要用到闭包
function build_sorter($key) {
return function ($a, $b) use ($key) {
if ($a[$key] == $b[$key]) {
return 0;
}
return ($a[$key] < $b[$key]) ? -1 : 1;
};
}
usort($goods, build_sorter('price'));
在类中定义这样的排序方法,usort()第二个参数需要使用数组传参,第一个属性为类名,第二个属性为方法名。
class Demo{
public function sort_by_type(&$goods){
usort($goods, array('self','compare'));
}
function compare($a, $b) {
if ($a['price'] == $b['price']) {
return 0;
}
return ($a['price'] < $b['price']) ? -1 : 1;
}
}
$demo = new Demo();
$demo->sort_by_type($goods);
如果想在类中定义可以按指定属性排序的方法,也是需要用到闭包的
class Demo{
public function sort_by_type(&$goods,$type){
function build_sorter($key) {
return function ($a, $b) use ($key) {
if ($a[$key] == $b[$key]) {
return 0;
}
return ($a[$key] < $b[$key]) ? -1 : 1;
};
}
usort($goods, build_sorter($type));
}
}
$demo = new Demo();
$demo->sort_by_type($goods,'price');
但注意到这个的闭包函数是写到了sort_by_type()方法中了,可以因为类中不支持那么复杂的调用,会提示找不到方法,代码如下(不可用)
class Demo{
public function sort_by_type(&$goods,$type){
usort($goods, array('self',build_sorter($type)));
}
function build_sorter($key) {
return function ($a, $b) use ($key) {
if ($a[$key] == $b[$key]) {
return 0;
}
return ($a[$key] < $b[$key]) ? -1 : 1;
};
}
}
$demo = new Demo();
$demo->sort_by_type($goods,'price');
会报错:
Fatal error: Call to undefined function build_sorter()
(如果有人知道怎么解决这个问题,还请指教)
所以如果想在类中使用按指定属性排序的方法,只能把闭包函数定义在方法内了,但有时候多次重复调用该方法时会出错(曾经碰到过),所以只适合在同一程序中使用一次的情况。