Ted's Blog



多条件排序原理分析

背景:在工作中有很多需要排序的需求,比如按照年龄排序,按照距离 或 按照特定信息特定顺序排序等。

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":"小米"}
]
分享:

写评论


Contact ME

github:https://github.com/tebie6

email:liumingyuphp@163.com

友情链接

无敌我大鑫哥:http://dream128.cn