php二维数组指定字段排序

十年热恋 提交于 2021-02-05 06:05:21

工作中遇到个问题,数据来自于excel,读取出来是二维数组,需要按照指定字段排序,类似于sql的order by功能,折腾了一会儿,代码如下:

class demo {
    public function test() {
        $arr = array(
            array(
                'power' => 380,
                'day' => 1,
                'where' => 1,
            ),
            array(
                'power' => 380,
                'day' => 2,
                'where' => 1,
            ),
            array(
                'power' => 400,
                'day' => 1,
                'where' => 1,
            ),
            array(
                'power' => 380,
                'day' => 3,
                'where' => 1,
            ),
            array(
                'power' => 400,
                'day' => 2,
                'where' => 1,
            ),
            array(
                'power' => 380,
                'day' => 8,
                'where' => 1,
            ),
            array(
                'power' => 380,
                'day' => 8,
                'where' => 2,
            ),
            array(
                'power' => 500,
                'day' => 1,
                'where' => 1,
            ),
            array(
                'power' => 380,
                'day' => 11,
                'where' => 1,
            ),
            array(
                'power' => 380,
                'day' => 5,
                'where' => 1,
            ),
        );

        $orderArr = array(
            'power' => 'asc',
            'day' => 'asc',
            'where' => 'asc',
        );

        // 调用排序函数
        $this->sortBySelf($arr, $orderArr);

        var_dump($arr);die;
    }


    /**
     * 自定义排序.
     *
     * @param array $arr   要排序的数组.
     * @param array $order 排序规则.
     *
     * @return array.
     */
    private function sortBySelf(&$arr = array(), $order = array()) {
        if (empty($order)) {
            return $arr;
        }

        $sortFuncNameArr = array(
            'desc' => 'descSortByKey',
            'asc' => 'ascSortByKey',
        );

        $index = array();

        $i = 0;
        $keys = array_keys($order);
        foreach ($order as $key => $value) {
            if ($i == 0) {
                $funcName = $sortFuncNameArr[$value];
                usort($arr, self::$funcName($key));
                // 定义第一个字段排序完的index
                $index = $this->setIndex($arr, array_slice($keys,0,$i+1));
                $i++;
                continue;
            }

            if (empty($index)) {
                break;
            }

            foreach ($index as $beSortKey => $range) {
                if (count($range) <= 1) {
                    continue;
                }

                $tmpSortArr = array_slice($arr, $range[0], count($range), true);

                $funcName = $sortFuncNameArr[$value];
                usort($tmpSortArr, self::$funcName($key));

                array_splice($arr, $range[0], count($range), $tmpSortArr);

                // 定义index
                $index = $this->setIndex($arr, array_slice($keys,0,$i+1));
            }

            $i++;
        }

    }

    /**
     * 每次排序完设置分区.
     *
     * @param array $arr       要排序的数组.
     * @param array $beSortKey 已经排序完的字段.
     *
     * @return array.
     */
    private function setIndex($arr = array(), $beSortKey = array()) {
        $index = array();

        foreach ($arr as $arrKey => $value) {
            $real = '';
            for ($i = 0; $i < count($beSortKey); $i++) {
                $real .= $value[$beSortKey[$i]];
            }
            $index[$real][] = $arrKey;
        }

        return $index;
    }

    /**
     * 倒序回调函数.
     *
     * @param string $key 要排序的KEY.
     *
     * @return Closure.
     */
    public static function descSortByKey($key = '') {
        return function ($a, $b) use ($key) {
            if ($a[$key] == $b[$key])
                return 0;
            return ($a[$key] > $b[$key]) ? -1 : 1;
        };
    }

    /**
     * 正序回调函数.
     *
     * @param string $key 要排序的KEY.
     *
     * @return Closure.
     */
    public static function ascSortByKey($key = '') {
        return function ($a, $b) use ($key) {
            if ($a[$key] == $b[$key])
                return 0;
            return ($a[$key] < $b[$key]) ? -1 : 1;
        };
    }

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