#日常积累# 将一个二维数组按元素类别(大类+小类)进行打散重新排序

需求大概如下:
 
有一个N个元素的数组要按下面的要求进行排序,这N个元素分别是一个个手机,每个手机都有自己的品牌属性,假设有两大品牌,华为A和小米B,实体手机会有:
华为手机(A1),
小米又分为
小米8(B2)、
小米6(B3)、
小米MIX(B4)。

然后要实现以下排序规则:

1、当某一类数据(AB两大类或B大类中的小类)连续超过3条时,按顺序将后面另一类型数据插入到第2条之后。优先进行AB类数据之间的相互插入,当A类数据不足时,进行B类中各小类数据的相互插入。
2、特殊规则:前2条数据为B类时,将后面第1条A类数据插入到第一条B类数据之后,后面数据的插入规则沿用2中描述的规则。

eg:
原顺序:B2,B2,A1,B2,B3,B4,A1,A1,A1,A1,B3,B3,B3,B3,B2
新顺序:B2,A1,B2,B2,A1,B3,B4,A1,A1,B3,A1,B3,B3,B2,B3

这个算法可以怎么实现?
 
按这个需求,想了很久并没有想到合适的办法。后来更改了下规则,将AB大类进行穿插打散,然后如果B类数据偏多,再将多余的B类数据,按照B小类进行穿插打散。实现代码如下:
 
/*
*1 华为手机
*3 小米手机5
*4 小米手机6
*5 小米手机8
*8 小米MIX
*9 小米MIX2S
*
*/
function phoneBreakUp($phone_list,$sort_by = 'phone_type')
{

//定义规则
$rule = [
'huawei' => [1],
'xiaomi' => [3,4,5,8,9]
];

//循环每类房源的数据,将华为和小米区分开
foreach ($phone_list as $key => $value) {

if(in_array($value[$sort_by], $rule['huawei'])){
$temp_phone_list['huawei'][] = $value;

}else{
$temp_phone_list['xiaomi'][] = $value;
}
}


//将华为数据和小米数据进行穿插处理
if(count($temp_phone_list['xiaomi']) >= count($temp_phone_list['huawei'])){

//首先把能够穿插的华为数据穿插处理
$break_phone_list = alternateArray($temp_phone_list['xiaomi'],$temp_phone_list['huawei']);

//如果小米类的数量比华为的多,还需要在剩余的小米数据里,进行穿插处理
for($i=2 * count($temp_phone_list['huawei']) + 1 ; $i < count($break_phone_list); $i++ ){
$whole_rent_list[$break_phone_list[$i][$sort_by]][] = $break_phone_list[$i];

}

//将获得的多余的小米数据进行穿插处理
$new_rent_list = alternateArrayMore($whole_rent_list);

//将穿插后的小米数据,替换掉大数组中的后面部分
array_splice($break_phone_list,2 * count($temp_phone_list['huawei']) + 1,count($break_phone_list) - 2 * count($temp_phone_list['huawei']) - 1,$new_rent_list);


}else{
$break_phone_list = alternateArray($temp_phone_list['huawei'],$temp_phone_list['xiaomi']);
}



return $break_phone_list;
}


/**
*
* 将华为和小米数据进行穿插(大类之间穿插)
*
*/
function alternateArray($big_array, $small_array)
{

$total_counts = count($big_array) + count($small_array);
$big_counts = $small_counts = 0;

for($i=0 ; $i< $total_counts; $i++){

if($i%2 == 0 && $small_counts < count($small_array)){
$break_up_list[$i] = $big_array[$big_counts];
$big_counts++;
}elseif($i%2 != 0 && $small_counts < count($small_array)){
$break_up_list[$i] = $small_array[$small_counts];
$small_counts++;
}else{
$break_up_list[$i] = $big_array[$big_counts];
$big_counts++;
}
}

return $break_up_list;

}


/**
*
* 将多余小米数据进行穿插(小类之间穿插)
*
*/
function alternateArrayMore($more_array)
{
//将二维数组依据二维元素的个数进行排序
foreach ($more_array as $key => $value) {
$more_array[$key]['counts'] = count($value);
}
array_multisort($more_array,SORT_DESC);

foreach ($more_array as $key => $value) {
unset($more_array[$key]['counts']);
}



//一直循环,直到取出二维数组中的所有元素
while (!empty($more_array)) {
foreach ($more_array as $key => $value) {
if(!empty($value)){
$break_up_list[] = array_pop($more_array[$key]);
}else{
//如果某个二维数组元素已经取尽,销毁掉
unset($more_array[$key]);
}
}
}

return $break_up_list;
}

0 个评论

要回复文章请先登录注册