我有一个数组,其中包含一个带有名称的数组,然后是一个总量。然后根据总排名为该阵列分配“总分”。每个等级的积分减少2,但我的问题是如何处理关系?理想情况下,我会看到有多少关系,将这些排名的总积分相加,然后将它除以有多少关系,但我不知道如何真正实现这一点
这是我的数组:
function grossSort($gross, $compare) {
if($gross['gross'] > $compare['gross'])
return -1; // move up
else if($gross['gross'] < $compare['gross'])
return 1; // move down
else
return 0; // do nothing
}
将我的数组转换为:
Array
(
[0] => Array
(
[instr] => lee
[gross] => 2094
)
[1] => Array
(
[instr] => steve
[gross] => 1334
)
[2] => Array
(
[instr] => nick
[gross] => 0
)
[3] => Array
(
[instr] => amber
[gross] => 0
)
[4] => Array
(
[instr] => lindsey
[gross] => 0
)
)
现在我正在做点什么来分配点数:
$maxpoints = 40;
for($i = 0; $i < count($trainergross); $i++){
$trainergross[$i]['points'] += $maxpoints;
$maxpoints -=2;
}
现在我的数组看起来像这样:
Array
(
[0] => Array
(
[instr] => lee
[gross] => 2094
[points] => 40
)
[1] => Array
(
[instr] => steve
[gross] => 1334
[points] => 38
)
[2] => Array
(
[instr] => nick
[gross] => 0
[points] => 36
)
[3] => Array
(
[instr] => amber
[gross] => 0
[points] => 34
)
[4] => Array
(
[instr] => lindsey
[gross] => 0
[points] => 32
)
)
这是我的问题,有4个人“捆绑”但是得到了降低点,我不知道如何以我当前的代码设置的方式来解决这个问题。有人有任何指导吗?
答案 0 :(得分:1)
您可以在迭代时存储最后一个已知值,并且只在值更改时减少点数。数组已排序,因此相等的元素将相邻。
/**
* award average of points to a number of elements.
* @param arrayref $trainergross - reference to the original array
* @param int $award - total points to award
* @param int $start_index - which element to start with?
* @param int $count - how many elements should be awarded points?
* @return void
*/
function award_points(&$trainergross, $award, $start_index, $count=1)
{
if(!$count || $award<1) return; // if noone is waiting for the award, OR there is no award, bail out
// $awards holds total award, and we need to
$avgPoints = $award / $count;
// award points to $count previous elements
for($j = $start_index; $j < $start_index + $count; ++$j)
{
// in case points key was not initialized, php will issue a notice.
if(!isset($trainergross[$j]['points'])) $trainergross[$j]['points'] = 0;
$trainergross[$j]['points'] += $avgPoints;
}
}
/**
* This is increased on purpose
* the first check will be <some number> vs null, which will result in -=2.
* this is to eliminate additional !== null test inside the loop.
*/
$maxpoints = 42;
// This will be used to store number of consecutive elements
$count = 0;
// This will be used to store total points to award
$award = 0;
// Here we will store last gross value
$last = null;
for($i = 0; $i < count($trainergross); $i++)
{
$maxpoints -= 2;
// if gross has not changed, just count consecutive elements and continue
if($last == $trainergross[$i]['gross'])
{
$award += $maxpoints;
$count++;
continue;
}
// store gross value
$last = $trainergross[$i]['gross'];
// now really distribute the points we've gathered in award by now
award_points($trainergross, $award, $i - $count, $count);
// reset count back to 1 (there is only 1 "consecutive" element now)
$count = 1;
// next element will get this award
$award = $maxpoints;
}
// now we have to award points again
// the loop ended, but $count of elements are still awaiting points...
award_points($trainergross, $award, $i - $count, $count);
答案 1 :(得分:0)
您可以利用分数排序的事实;对于每次迭代,您尝试找到尽可能多的相等分数,然后一次更新整批:
$trainergross = [
['instr' => 'lee', 'gross' => 2094],
['instr' => 'steve', 'gross' => 1334],
['instr' => 'nick', 'gross' => 0],
['instr' => 'amber', 'gross' => 0],
['instr' => 'lindsay', 'gross' => 0],
];
$maxpoints = 40;
for ($current = 0; $current < count($trainergross); $current = $next) {
// find the first unequal score and reduce points to calculate average later
$next = $current; $minpoints = $maxpoints;
while (++$next < count($trainergross) && $trainergross[$next]['gross'] == $trainergross[$current]['gross']) {
$minpoints -= 2;
}
if ($minpoints == $maxpoints) {
$trainergross[$current]['points'] = $maxpoints;
} else {
// tie, calculate average points to award
$points = floor(($maxpoints + $minpoints) / 2);
// update this batch
for ($i = $current; $i < $next; ++$i) {
$trainergross[$i]['points'] = $points;
}
}
// decrease the points for next iteration
$maxpoints = $minpoints - 2;
}
print_r($trainergross);