话不多说,上代码,不懂原理与目的可以对照注释
/**
* 根据给定的总数值返回每个单元的最值平均数
*
* @param integer $num 总共需要被平均的值
* @param array $data 提供的数据
*
* @example $num = 12
* $data = [
* "a" => 5,
* "b" => 6,
* "c" => 2,
* ]
*
* @return [
* "a" => 5,
* "b" => 5,
* "c" => 2,
* ]
*/
if (! function_exists('get_avg_data')) {
function get_avg_data($num, array $data)
{
$sum = array_sum($data);
// 如果数组内小于需要数值
if ($num >= $sum){
$reData = $data;
} else {
asort($data);
$reData = handle_avg_data($num, $data);
}
return $reData;
}
}
// 处理数据
if (!function_exists('handle_avg_data')){
function handle_avg_data(&$num, array &$data)
{
$n = count($data);
$avg = (int)($num / $n);
$y = $num % $n;
$reData = [];
$preData = $data;
foreach ($data as $key => $value) {
if ($value <= $avg){
$reData[$key] = $value;
unset($data[$key]);
$num = $num - $value;
}
}
if (count($preData) == count($data)){
if ($y == 0){
foreach ($data as $k => $v){
$reData[$k] = $avg;
unset($data[$k]);
}
} else {
foreach ($data as $k => $v){
$reData[$k] = $avg + 1;
$num = $num - $avg - 1;
unset($data[$k]);
break;
}
}
}
$reD = [];
if (count($data) > 0){
$reD = handle_avg_data($num, $data);
}
return array_merge($reData, $reD);
}
}
好吧,再举一个例子eg①:我总共需要30条数据,数据库中满足条件的有4类数据,他们总数分别是4,5,15,19条。
我要获得尽可能理想的数据,那么应该分别返回 4,5,11,10条。
eg②:我总共需要30条数据,数据库中满足条件的有4类数据,他们总数分别是12,6,15,19条。
我要获得尽可能理想的数据,那么应该分别返回 8,6,8,8条。
……
上面的代码就实现了这一目的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。