一个对二维数组进行多字段多顺序排序的方法

点点圈 提交于 2020-04-06 05:28:14

1,代码

<?php

/**
 * 对二维数组依次按照排序规则数组指定的字段和顺序进行排序,在有相同的情况下按下一个字段和顺序进行排序
 * @param array $arr 待排序的数组
 * @param array $fieldSortMap:排序规则数组, 一维关联数组,每个元素的键为排序字段名称,值为排序方向:SORT_ASC升序或SORT_DESC降序
 * @return array
 */
function multiSortByFields(array $arr, array $fieldSortMap) {
    $count = count($arr);
    if ($count <= 1 || empty($fieldSortMap)) {
        return $arr;
    }
    $params = [];
    //将排序字段所拥有的值分别放入数组中,以备排序
    foreach ($fieldSortMap as $field => $sort) {
        //field值数组,必须每个元素中都要有
        $fieldValues = array_column($arr, $field);
        if (count($fieldValues) != $count) {
            return $arr;
        }
        //准备参数:依次分别是排序field的值数组和对应的排序方向(升序,降序)
        $params[] = $fieldValues;
        $params[] = $sort == SORT_ASC ? SORT_ASC : SORT_DESC;
//        $params[] = SORT_NUMERIC;
    }
    //将原数组放入
    $params[] = &$arr;
    //排序
    array_multisort(...$params);

    return $arr;
}

核心思想是用 array_multisort() 方法,通过对字段的排序,最终影响数组的排序。

2,测试

$a = [
    [
        'a' => 1,
        'b' => 111
    ],
    [
        'a' => 0,
        'b' => 111
    ],
    [
        'a' => 3,
        'b' => 333
    ],
    [
        'a' => 4,
        'b' => 333
    ],
];
//先按b字段的值倒序排序,如b字段的值相同,则按a字段的值升序排序
$fieldSortMap = [
    'b' => SORT_DESC,
    'a' => SORT_ASC
];
$res = multiSortByFields($a, $fieldSortMap);
var_dump($res);

结果

array(4) {
  [0]=>
  array(2) {
    ["a"]=>
    int(3)
    ["b"]=>
    int(333)
  }
  [1]=>
  array(2) {
    ["a"]=>
    int(4)
    ["b"]=>
    int(333)
  }
  [2]=>
  array(2) {
    ["a"]=>
    int(0)
    ["b"]=>
    int(111)
  }
  [3]=>
  array(2) {
    ["a"]=>
    int(1)
    ["b"]=>
    int(111)
  }
}

3,思考

这里只是二维数组,看能否用 array_walk_recursive() 递归地实现 对多维数组的多字段多方向排序。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!