樂猪先生

PHP多维数组排序之array_multisort

2017-08-20

在上一篇中我使用了usort这个函数来排序多维数组,以及根据数组里的2个字段来排序数组。然而PHP也提供了一个专门给多维数组排序的函数array_multisort,所以今天来学习一下这个函数也和usort比较一下具体的区别。

首先看一下这个函数的原型

1
bool array_multisort ( array &$array1 [, mixed $array1_sort_order = SORT_ASC [, mixed $array1_sort_flags = SORT_REGULAR [, mixed $... ]]] )

首先我们需要生成一个排序数组array1,然后给出一个排序规则比如SORT_ASC这个默认常量,与之对应的当然是SORT_DESC
先简单看一下使用TotalPrice这个字段来对数组进行倒序排序

1
2
3
4
foreach ($hotelList as $key => $v) {
$totalPrice[] = $v['TotalPrice'];
}
array_multisort($totalPrice, SORT_DESC, $hotelList); //默认SORT_ASC可以省略,而SORT_DESC不能省略

得到如下排序后的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
array:7 [▼
0 => array:4 [▼
"LastId" => 32778
"Time" => "2017-07-24T01:38:09+08:00"
"OrderId" => 171868405
"TotalPrice" => 700
]
1 => array:4 [▼
"LastId" => 32749
"Time" => "2017-07-24T01:35:25+08:00"
"OrderId" => 171868375
"TotalPrice" => 400
]
2 => array:4 [▼
"LastId" => 32714
"Time" => "2017-07-24T10:36:33+08:00"
"OrderId" => 171868350
"TotalPrice" => 200
]
3 => array:4 [▼
"LastId" => 32731
"Time" => "2017-07-24T00:38:00+08:00"
"OrderId" => 171868367
"TotalPrice" => 200
]
4 => array:4 [▼
"LastId" => 32733
"Time" => "2017-07-24T09:20:00+08:00"
"OrderId" => 171868366
"TotalPrice" => 200
]
5 => array:4 [▼
"LastId" => 32757
"Time" => "2017-07-24T01:36:00+08:00"
"OrderId" => 171868383
"TotalPrice" => 160
]
6 => array:4 [▼
"LastId" => 32769
"Time" => "2017-07-24T01:36:59+08:00"
"OrderId" => 171868395
"TotalPrice" => 150
]
]

可以看到,使用这个函数必须先拿到一个排序数组,比usort稍微繁琐一点。但是如果我们在PHP版本大于5.5以上可以这样来写,一步到位。

1
array_multisort(array_column($hotelList, 'TotalPrice'), SORT_ASC, $hotelList);

这个函数还有第三个flag参数,没怎么用到,不过也很好理解。只是项目里用默认的就可以,除非一些特殊情况。目前还没想到哪些场景要修改flag,所以这里也就不讨论了。接下来我们使用2个字段来同时对数组进行排序。

1
2
3
4
5
foreach ($hotelList as $key => $v) {
$totalPrice[] = $v['TotalPrice'];
$time[] = $v['Time'];
}
array_multisort($totalPrice, SORT_ASC, $time, SORT_DESC, $hotelList);

如果所有字段都是正序那么可以省略SORT_ASC参数,即

1
array_multisort($totalPrice, $time, $hotelList);

那么PHP5.5+的写法就很明白了,自己想吧。

结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
array:7 [▼
0 => array:4 [▼
"LastId" => 32769
"Time" => "2017-07-24T01:36:59+08:00"
"OrderId" => 171868395
"TotalPrice" => 150
]
1 => array:4 [▼
"LastId" => 32757
"Time" => "2017-07-24T01:36:00+08:00"
"OrderId" => 171868383
"TotalPrice" => 160
]
2 => array:4 [▼
"LastId" => 32714
"Time" => "2017-07-24T10:36:33+08:00"
"OrderId" => 171868350
"TotalPrice" => 200
]
3 => array:4 [▼
"LastId" => 32733
"Time" => "2017-07-24T09:20:00+08:00"
"OrderId" => 171868366
"TotalPrice" => 200
]
4 => array:4 [▼
"LastId" => 32731
"Time" => "2017-07-24T00:38:00+08:00"
"OrderId" => 171868367
"TotalPrice" => 200
]
5 => array:4 [▼
"LastId" => 32749
"Time" => "2017-07-24T01:35:25+08:00"
"OrderId" => 171868375
"TotalPrice" => 400
]
6 => array:4 [▼
"LastId" => 32778
"Time" => "2017-07-24T01:38:09+08:00"
"OrderId" => 171868405
"TotalPrice" => 700
]
]

1
2
3
4
5
6
7
$incrOrderList = array_reduce($incrOrderList,
function($rst, $v) {
$rst[$v['OrderId']] = $v;
return $rst;
}, array()
);
$incrOrderList = array_values($incrOrderList);//为了变成{[]}