我想根据我的玩家有多少朋友来给他们奖金。
我有断点(例如0、1、5、10、25)
对于0个朋友,他将获得0奖励。
对于1个朋友,他可以得到1000,对于5个或以上的2000等等…
我现在做的是:
public function getFriendsBonusByFriendsAmount($amount)
{
switch (true) {
case ($amount < 1):
return 0;
case ($amount < 5):
return 1000;
case ($amount < 10):
return 2000;
case ($amount < 25):
return 3000;
case ($amount >= 25):
return 5000;
}
}
我正在寻找一种不同的方式来寻找奖金,而无需foreach/switch
也许想想我可以玩的一个或多个数组?
$bonusBreakpoints = [
0 => 0,
1 => 1000,
5 => 2000,
10 => 3000,
25 => 5000
]
或者可能是两个具有各自索引的数组?
我想了一种方法,但这是浪费内存:
$bonusPerFriends = [
0 => 0,
1 => 1000,
2 => 1000,
3 => 1000,
4 => 1000,
5 => 2000,
6 => 2000,
...
25 => 5000
]
我宁愿不用那种方法。
好吧,有时foreach/switch
将是最好的解决方案:)
/**
* Calculates bonus based on how many
* friends the player have from predefined breakpoints
**/
function getBonus($friends) {
$bonuses = [0, 1000, 2000, 3000, 5000];
$stops = [[PHP_INT_MIN, 0], [1, 4], [5, 14], [15, 24], [25, PHP_INT_MAX]];
// replace the stops by bonus if match, otherwise return empty - O(n)
$bonus = array_map(function ($stop, $bonus) use ($friends) {
if ($friends >= $stop[0] && $friends <= $stop[1]) {
return $bonus;
}
}, $stops, $bonuses);
// clean up the array from empty values - O(n)
$bonus = array_filter($bonus , 'is_numeric');
// from array(3 => 3000) to 3000 - O(1)
return array_pop($bonus);
}
结果:
echo getBonus(0).PHP_EOL; // 0
echo getBonus(4).PHP_EOL; // 1000
echo getBonus(12).PHP_EOL; // 2000
echo getBonus(20).PHP_EOL; // 3000
echo getBonus(39).PHP_EOL; // 5000
此处的p.S.$bonuses
和$stops
的长度必须相等。
@andrey mischenko的答案在技术上是正确的,但正如你在问题中所说,如果没有foreach,就无法解决问题 (编辑:答案已删除)试试这个:
$bonusBreakpoints = [
0 => 0,
1 => 1000,
5 => 2000,
10 => 3000,
25 => 5000
];
$justTheKeys = array_keys($bonusBreakpoints);
public function getFriendsBonusByFriendsAmount($amount)
{
$bonus = array_reduce($justTheKeys, function($carryOver, $item) use ($amount)
{
if ($amount >= $item) return $bonusBreakpoints($item);
return $carryOver;
}
return $bonus;
}
(我知道这不是array_reduce
最初的目的。我把这个问题理解为一个心理游戏。比如"除了明显的方法,比如循环或开关,找到创造性的方法来解决这个问题。"如果我必须为工作编写代码,我可能也会使用循环。:)
在阅读了答案和更多研究后,我得出结论,二进制搜索是我的最佳选择。
数据看起来应该有点像这样:
$bonuses = [
[ 'min' => 0, 'max' => 0, 'amount' => 0 ]
[ 'min' => 1, 'max' => 4, 'amount' => 1000 ]
[ 'min' => 5, 'max' => 14, 'amount' => 2000 ]
...
[ 'min' => 25, 'max' => PHP_INT_MAX, 'amount' => 5000 ]
]
你从count($bonuses)/2
开始,从那里检查你是否低于最小值,是这样的,走到一半,否则检查你是否高于最大值,然后走到一半。其他的只要退还奖金,因为你在正确的范围内。
由于我的大多数用户没有朋友或超过25个,我可能会先检查第一个和最后一个单元格。