在写评论系统的时候遇到一个排序的问题,评论列表展示的时候支持父子层级和无限层级两种。数据都是递归出来的,无限层级大概长这样:
┌── 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还是蛮有意思,继续加油吧。