多条件排序原理分析
背景:在工作中有很多需要排序的需求,比如按照年龄排序,按照距离 或 按照特定信息特定顺序排序等。
1、单字段条件排序
[
{"age":"7"},
{"age":"6"},
{"age":"2"},
{"age":"3"},
{"age":"8"}
]比如这一串json数据 按照年龄排序,实现很简单
大概过程就是 将 age值 拿出来遍历对比排序
排序算法有:冒泡排序、归并排序、快速排序等
2、多字段条件排序
但是工作中也有很多多条件的排序,比如:根据年龄、手机型号、交通工具排序来筛选出前十的用户
这里我们列出一组练习数据
[
{"age":"20", "vehicle":"公交", "phone":"华为"},
{"age":"20", "vehicle":"地铁", "phone":"苹果"},
{"age":"20", "vehicle":"开车", "phone":"小米"},
{"age":"22", "vehicle":"公交", "phone":"华为"},
{"age":"22", "vehicle":"地铁", "phone":"苹果"},
{"age":"22", "vehicle":"开车", "phone":"小米"},
{"age":"21", "vehicle":"公交", "phone":"华为"},
{"age":"21", "vehicle":"地铁", "phone":"苹果"},
{"age":"21", "vehicle":"开车", "phone":"小米"}
]需求:
我们按照 年龄 ASC,交通工具 (地铁、开车、公交)顺序,手机(华为、小米、苹果)顺序 来排序
问题:
根据上面的需求我们分析一下排序需要处理的内容
1、交通工具 (地铁、开车、公交) 这类自定义顺序如何处理?
2、多条件排序如何排序?
解答:
问题一,我们可以根据自定义的顺序为每一个枚举类型设置权重值
例如:地铁 - 1, 开车 - 2, 公交 - 3
问题二,多字段排序原理就是从最边缘条件开始一次对数据排序
代码示例:
<?php
// php 官方demo
function array_orderby()
{
$args = func_get_args();
$data = array_shift($args);
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
$data = []; // 需要排序的数据
// 交通权重
$vehicleSort = [
'地铁' => 1,
'开车' => 2,
'公交' => 3,
];
// 手机权重
$phoneSort = [
'华为' => 1,
'小米' => 2,
'苹果' => 3,
];
// 排序内容替换成权重值
foreach ($data as $key => $item) {
$data[$key]['vehicle'] = $vehicleSort[$item['vehicle']] ?? 999;
$data[$key]['phone'] = $phoneSort[$item['phone']] ?? 999;
}
// 排序
$sorted = array_orderby($data, 'age', SORT_ASC, 'vehicle', SORT_ASC, 'phone', SORT_ASC);
// 权重值恢复对应名称
foreach ($data as $key => $item) {
$sorted[$key]['vehicle'] = array_search($item['vehicle'], $vehicleSort);
$sorted[$key]['phone'] = array_search($item['phone'], $phoneSort);
}
echo json_encode($sorted, JSON_UNESCAPED_UNICODE).PHP_EOL;
// sorted
[
{"age":"20","vehicle":"公交","phone":"华为"},
{"age":"20","vehicle":"地铁","phone":"苹果"},
{"age":"20","vehicle":"开车","phone":"小米"},
{"age":"21","vehicle":"公交","phone":"华为"},
{"age":"21","vehicle":"地铁","phone":"苹果"},
{"age":"21","vehicle":"开车","phone":"小米"},
{"age":"22","vehicle":"公交","phone":"华为"},
{"age":"22","vehicle":"地铁","phone":"苹果"},
{"age":"22","vehicle":"开车","phone":"小米"}
]