多维数组扁平化处理

1.源起

刚开始只是想把with一对一关联出来的合并到外面数组上(又不想用那个API资源一层一层的去套),
后面又遇到一对多的想想还是加上了(好像弄出来个鸡肋操作啊,哈哈哈)

2.程序代码
/**
     * 数组数据扁平化筛选返回
     *
     * @param array $data 需筛选结果集
     * @param array $endData 最终返回数据格式下标数组
     * @param array $screenData with关联筛选返回数据格式拼接集
     * @param array $manyData 数组返回字段集(预防返回数据为空时,类型问题)
     * @param array $defaults 默认值数组
     * @param int $type 执行数据是否是一条  0 否  1 是
     * @param int $notFound 是否空字符和null即删除  0 否  1 是
     * @return array
     */
    public static function partWith(
        $data = [],
        array $endData = [],
        array $screenData = [],
        array $manyData = [],
        $defaults = [],
        $type = 0,
        $notFound = 0
    )
    {
        if (!is_array($data)) {
            return $data;
        }
        if ($type) {
            //循环需要拆分数组   $screenIndex   with关联筛选字段   $screenValue  返回别名
            foreach ($screenData as $screenIndex => $screenValue) {
                if (array_key_exists($screenIndex, $data)) {
                    $data = self::withSplit($screenValue, $data[$screenIndex], $data);
                }
            }
            /**
             * 循环一对多/数组型返回数据
             * 判断当前扁平化数据是否存在一对多下标
             * 存在及递归访问数据扁平化
             * $manyData 多条数据
             * $manyDataValue[0] 最终扁平化结果
             * $manyDataValue[1] 数据筛选数组
             */
            foreach ($manyData as $manyDataItem => $manyDataValue) {
                if (array_key_exists($manyDataItem, $data)) {
                    if (isset($manyDataValue[1][0])) {
                        $data[$manyDataItem] = self::partWith($data[$manyDataItem], $manyDataValue[0], ...$manyDataValue[1]);
                    } else {
                        $data[$manyDataItem] = self::partWith($data[$manyDataItem], $manyDataValue[0], isset($manyDataValue[1])?$manyDataValue[1]:[]);
                    }
                }
            }
            $data = self::endDataSplicing($endData, $manyData, $data, $defaults, $notFound);
        } else {
            foreach ($data as $dataIndex => $dataValue) {
                //循环需要拆分数组   $screenIndex   with关联筛选字段   $screenValue  返回别名
                foreach ($screenData as $screenIndex => $screenValue) {
                    //判断当前筛选下标是否在一级数组
                    if (array_key_exists($screenIndex, $dataValue)) {
                        //当前一级数组筛选字段,当前筛选下标数组数据,当前一级数组全部数据,
                        $dataValue = self::withSplit($screenValue, $dataValue[$screenIndex], $dataValue);
                    }
                }
                /**
                 * 循环一对多/数组型返回数据
                 * 判断当前扁平化数据是否存在一对多下标
                 * 存在及递归访问数据扁平化
                 * $manyData 多条数据
                 * $manyDataValue[0] 最终扁平化结果
                 * $manyDataValue[1] 数据筛选数组
                 */
                foreach ($manyData as $manyDataItem => $manyDataValue) {
                    if (array_key_exists($manyDataItem, $dataValue)) {
                        if (isset($manyDataValue[1][0])) {
                            $dataValue[$manyDataItem] = self::partWith($dataValue[$manyDataItem], $manyDataValue[0], ...$manyDataValue[1]);
                        } else {
                            $dataValue[$manyDataItem] = self::partWith($dataValue[$manyDataItem], $manyDataValue[0], isset($manyDataValue[1]) ? $manyDataValue[1] : []);
                        }
                    }
                }
                $data[$dataIndex] = self::endDataSplicing($endData, $manyData, $dataValue, $defaults, $notFound);
            }
        }
        return $data;
    }

    /**
       * with数据拼接第一层 
     * @param array $withName with关联字段更改集 
     * @param array $withData 当前with关联结果集 
     * @param array $endData 最终结果集 * @return mixed 
     */
    public static function withSplit($withName, $withData, $endData)
    {
        //循环当前一维数组筛选返回字段数组
        foreach ($withName as $index => $value) {
            //判断是否存在下级with关联,(多维数组)
            if ($withData && array_key_exists(0, $withData) && count($withData) == 1) {
                //取出第一个
                $withData = reset($withData);
            }
            //当前数据下是否有当前筛选的下标参数,并且当前数据下筛选的下标数据是数组
            if (isset($withData[$index]) && is_array($withData[$index])) {
                //当前需筛返回字段是否是数组
                if (is_array($value)) {
                    //递归重复,将最终返回结果字段添加到最外层
                    $endData = self::withSplit($value, $withData[$index], $endData);
                } else {
                    //当前数据存在
                    if ($withData) {
                        //将当前筛选下标的数据直接放在数据集中
                        $endData[$value] = $withData[$index];
                    }
                }
                //删除当前下标数据
                unset($withData[$index]);
            } else {
                /**
                 * 默认参数别名返回 
                * 类型整型不修改参数名,获取新下标 
                */
                $arrIndex = $index;
                if (gettype($index) == "integer") {
                    $arrIndex = $value;
                }
                if ($withData && isset($withData[$arrIndex])) {
                    //将当前筛选下标的数据直接放在数据集中
                    $endData[$value] = $withData[$arrIndex];
                }
            }
        }
        return $endData;
    }

    /**
      * 最终返回数组拼接 * * @param array $endData 最终返回数组下标数组
      * @param array $arrData 数组返回字段集
      * @param array $data 需筛选结果集
      * @param array $defaults 默认值数组
      * @param int $notFound 是否空字符和null及删除  0 否  1 是
      * @return array
      */
     public static function endDataSplicing($endData, $arrData, $data, $defaults, $notFound)
    {
        $arr = [];
        //是否存在最终返回数据下标自定义
        foreach ($endData as $endDataKey => $endDataValue) {
            /**
             * 默认参数别名返回 
             * 类型整型不修改参数名,获取新下标 
             */
            $arrIndex = $endDataKey;
            if (gettype($endDataKey) == "integer") {
                $arrIndex = $endDataValue;
            }
            //初步定义
            $arr[$endDataValue] = '';
            //是否存在数组返回集中
            if (array_key_exists($arrIndex, $arrData)) {
                $arr[$endDataValue] = [];
            }
            //是否存在筛选集
            if (array_key_exists($arrIndex, $data)) {
                $arr[$endDataValue] = $data[$arrIndex];
            }
            //最终数据是否存在,不存在检测是否赋默认值,有取默认值,无则直接返回
            $arr[$endDataValue] = (empty($arr[$endDataValue]) && ($arr[$endDataValue] !== 0) && ($arr[$endDataValue] !== false)) ?
         (array_key_exists($endDataValue, $defaults) ? $defaults[$endDataValue] : $arr[$endDataValue])
         : $arr[$endDataValue];
            //是否预设默认值,不存在删除,是否为空字符和null
            if ($notFound && ($arr[$endDataValue] === "" || $arr[$endDataValue] === null) && !array_key_exists($endDataValue, $defaults)) {
                unset($arr[$endDataValue]);
            }
        }
        return $arr;
    }
3.调用(因为我是加在新建的Tools类里面的,所以我调用是用Tools静态调用)
3.1 一对一数据调用
 //一条数据调用 
 $userInfo = Tools::partWith($userInfo, [
      'id', 'name', 'head', 'phone', 'birthday',
      'sex', 'seller_name','intro','images'
      ], [
        'get_seller'=>[
            'name'=>'seller_name',
            'intro',
            'images'
        ]
      ], [], ['images'=>[]], 1);
 //多条数据调用
 $userInfo = Tools::partWith($userInfo, [
        'id', 'name', 'head', 'phone', 'birthday',
        'sex', 'seller_name','intro',
        ], [
          'get_seller'=>[
              'name'=>'seller_name',
              'intro',
          ]
        ]);
Ps:一条数据调用,也就是多了参数
3.2 一对多数据调用
    //一堆多(with('get_activity')->with('get_activity_cate'))
    $info=Tools::partWith($info,[
                 'activity_id','publish_name', 'get_activity_cate' 
                 //重命名'get_activity_cate'=>'activity_cate'
             ],[ 
                 'get_activity'=>[ 
                     'publish_name', 
                 ] 
                 ],[ 
                     'get_activity_cate'=>[ 
                         //最后的返回字段 [ 
                         'expect_price', 
                         //'title 
                     ], 
                     //一对一关联数据,还有筛选参数请看最后的调用方式
                    //[ 
                    //     'get_model'=>[ 
                    //          'title' 
                    //     ] 
                    //] 
             ],['get_activity_cate'=>[]],1);
    //一对一对多(with('get_activity.get_activity_cate'))
    $info=Tools::partWith($info,[
         'activity_id','publish_name', 'get_activity_cate' 
         ],[ 
             'get_activity'=>[ 
                 'publish_name', 'get_activity_cate' 
             ] 
             ],[ 
                 'get_activity_cate'=>[
                     [ 
                     'expect_price' 
                     ] 
                 ] 
            ],1);
3.3 一对多对多对一对多数据调用(这个好像是用不着,hhh)
$data = Tools::partWith($data, [
 'name', 'head', 'id', 'get_order' 
 ],
 [], 
 [ 
 'get_order' => [//一对多订单数据 
     [ 
     'order_sn', 'order_type', 'get_order_detail' 
     ], 
         [//传参更改,展开数组 
             [],//等同一对一筛选数组 
             [ 
                 'get_order_detail' => [//一对多订单详情数据 
                     [ 
                         'order_id', 'good_spece_id', 'goods_id', 'title', 'goods_spece'
                     ], 
                     [
                         [ 
                             'get_goods' => [//一对一商品数据 
                            'title', 'id' => 'goods_id', 'get_goods_spece' => 'goods_spece'
                                ] 
                            ], 
                            [ 
                                'goods_spece' => [//一对多商品规格数据
                                    [ 
                                        'title' => 'spece_title' 
                                    ] 
                                ] 
                            ] 
                        ]
                    ] 
                ]//等同一对多筛选数组 
            ] 
        ] 
    ]);
BUG制造者
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2
自由与温暖是遥不可及的梦想

需要写的这么复杂么? 写的太复杂了 可以多看看 集合《Laravel 7 中文文档》

4年前 评论
小猪蹄子 (楼主) 4年前

如果我没有记错,laravel有个map方法,数组平滑等等操作的...

4年前 评论
小猪蹄子 (楼主) 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!