多维数组扁平化处理
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'
]
]
]
]
]
]//等同一对多筛选数组
]
]
]);
需要写的这么复杂么? 写的太复杂了 可以多看看 集合《Laravel 7 中文文档》
如果我没有记错,
laravel
有个map
方法,数组平滑等等操作的...