多条件排序原理分析
背景:在工作中有很多需要排序的需求,比如按照年龄排序,按照距离 或 按照特定信息特定顺序排序等。
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":"小米"} ]