在写评论系统的时候遇到一个排序的问题,评论列表展示的时候支持父子层级和无限层级两种。数据都是递归出来的,无限层级大概长这样:

┌── 21
│   ├── 24
│   │   ├── 28
│   │   │   └── 30
│   │   │       └── 33
│   │   └── 29
│   │       └── 34
│   ├── 25
│   │   ├── 31
│   │   └── 32
│   └── 26
├── 22
│   └── 27
├── 23

父子层级就是把所有的子级都放在第二层,但是因为是递归出来的,列表的顺序可能是这样:

┌── 21 
│   ├── 24
│   ├── 28
│   ├── 30 
│   ├── 33 
│   ├── 29 
│   ├── 34 
│   ├── 25 
│   ├── 31 
│   ├── 32
│   └── 26
├── 22
│   └── 27
├── 23

子级里面的顺序是遍历的顺序,而不是时间顺序,那么需要对二级列表进行排序,二级列表是一个对象数组,在PHP里面可能没那么明确,也可以叫二维数组。现在需要对这个对象数组按照对象的创建时间进行排序。

查询了PHP的数组排序文档,基本上都是对一维数组进行操作的,比如对普通数组排序,对键值数组按照键或者值排序,6中排序都实现不了我的需求。

后面查到有一个array_multisort()函数,可以对多个数组进行排序。

array_multisort() 语法:

array_multisort(array1, sort_order, sort_flags, array2, array3...)
参数描述
array必需。要排序的 array
sort_order可选。规定排列顺序。
可能的值:SORT_ASC - 默认。按升序排列 (A-Z)。SORT_DESC - 按降序排列 (Z-A)。
sort_flags可选。规定排序类型。
SORT_REGULAR - 将项目按照通常方法比较(不修改类型)
SORT_NUMERIC - 按照数字大小比较
SORT_STRING - 按照字符串比较
SORT_LOCALE_STRING - 根据当前的本地化设置,按照字符串比较。 它会使用 locale 信息,可以通过 setlocale() 修改此信息。
SORT_NATURAL - 以字符串的"自然排序",类似 natsort()
SORT_FLAG_CASE - 可以组合 (按位或 OR) SORT_STRING 或者 SORT_NATURAL 大小写不敏感的方式排序字符串。
参数可以和 array1_sort_order 交换或者省略,默认情况下是 SORT_REGULAR
array2可选。规定数组。
array3可选。规定数组。

光看这个语法说明可能有点不太好理解,这个函数是先以指定的规则对数组1进行排序,然后按照数组1中的排好的顺序来排后面的数组2、数组3....,每个数组中的初始顺序要一致,比如:

$grade1 = array('mathematics' => '130', 'physics' => '110', 'chemistry' => '140', 'english' => '100');
$grade2 = array('mathematics' => '110', 'physics' => '130', 'chemistry' => '140', 'english' => '100');
$grade3 = array('mathematics' => '80', 'physics' => '140', 'chemistry' => '110', 'english' => '130');

array_multisort($grade1, SORT_ASC, $grade2, $grade3);
// 排序后的结果
$grade1 = array('english' => '100', 'physics' => '110', 'mathematics' => '130', 'chemistry' => '140');
$grade2 = array('english' => '100', 'physics' => '130', 'mathematics' => '110', 'chemistry' => '140');
$grade3 = array('english' => '130', 'physics' => '140', 'mathematics' => '80', 'chemistry' => '110');

那么如何用这个函数来实现我现在的排序需求呢,我需要先将第一个参数要排序的字段数组拿到,这时候需要用到另一个函数:array_column() 返回输入数组中某个单一列的值。

array_column() 语法:

array_column(array, column_key, index_key);
参数描述
array必需。规定要使用的多维数组(记录集)。
column_key必需。需要返回值的列。可以是索引数组的列的整数索引,或者是关联数组的列的字符串键值。该参数也可以是 NULL,此时将返回整个数组(配合 index_key 参数来重置数组键的时候,非常有用)。
index_key可选。用作返回数组的索引/键的列。

先用这个接口取出列表中的时间,再调用array_multisort(),对要排序的数组按照时间顺序排序:

$sort_array = array_column($item["childList"], 'create_time');
array_multisort($sort_array, SORT_ASC, $item["childList"]);

$item["childList"]为要排序的对象列表,从中取出时间,按照正序排列,然后再对列表按照时间排序。最终的效果如下:

┌── 21 
│   ├── 24
│   ├── 25
│   ├── 26 
│   ├── 28 
│   ├── 29 
│   ├── 30 
│   ├── 31 
│   ├── 32 
│   ├── 33
│   └── 34
├── 22
│   └── 27
├── 23

学习PHP还是蛮有意思,继续加油吧。

Last modification:June 8th, 2020 at 06:52 pm
If you think my article is useful to you, please feel free to appreciate