【问题标题】:PHP function to match key in a range of valuesPHP函数匹配一系列值中的键
【发布时间】:2011-03-23 15:58:55
【问题描述】:

我有一个带有lvl=>xp 对应关系的数组,我会创建一个函数来返回特定xp 的lvl。喜欢$lvl = getLvlOf(15084); //return 5

$lvl_correspondance = array(
    1=>100,
    2=>520,
    3=>2650,
    4=>6588,
    5=>12061,
    6=>23542,
    ...
    n=>xxxxxx
);

我寻找最简单且无资源的方法。

对不起我的英语不好:(

【问题讨论】:

    标签: php arrays function


    【解决方案1】:

    假设数组中的级别值保持排序,例如(它是 100,200,300、400 等……而不是 200,500,100,300,400),那么简单的扫描就可以解决问题:

    $xp = 15084;
    $last_key = null;
    foreach($lvl_correspondenance as $key => $val) {
        if ($val < $xp) {
            $last_key = $key;
        } else {
            break;
        }
    }
    

    这将遍历数组,并在数组中的 XP 级别大于您要查找的 XP 级别时立即跳出,将“最后”级别的键留在 $last_key 中

    【讨论】:

    • 不应该是if ($val &lt;= $xp) 吗?
    • 取决于你是在达到 100(比如说)还是 101 时被提升到更高的水平,我猜。
    【解决方案2】:
    function getLvlOf($lvl, $int){
            foreach($lvl as $level=>$exp){
                    if($exp > $int){
                            return $level-1;
                    }
            }
    }
    

    它是 O(n),所以没有魔法......

    【讨论】:

      【解决方案3】:

      看起来你的数组可以实时计算 -

      XP = exp( 3 * ln(LVL) + 4 ) * 2

      你可以反过来做同样的事情,在 O(1) 中:

      LVL = exp(ln(XP/2) - 4 / 3)

      我对等式进行了四舍五入,因此可能存在 +/- 1 的问题

      祝你好运!

      【讨论】:

      • 如果它可以实时计算,那将是一个完美的选择。我已经尝试过这样做,但是有 100 lvl,我没有找到适合的公式。但是非常感谢您的帮助。
      • 也许你可以在这里找到一个带有真实数据的公式spreadsheets.google.com/…
      • 最佳拟合是 4 阶多项式:XP = 0.014*L^4 - 1.83*L^3 + 108.67*L^2 - 1563.36*L + 6830 这太荒谬了,如果你知道这些数字最初来自哪里会更好
      【解决方案4】:

      如果你有很高的价值,那就不好了,但是:

      $lvl = $lvl_correspondance[array_search(
                                       max(array_intersect(
                                                 array_values($lvl_correspondance),
                                                              range(0,$points)
                                                             )
                                          ),
                                       $lvl_correspondance
                                      )];
      

      【讨论】:

      • 这是一个好主意,但对于我的价值类型来说,它的表现真的很差。感谢您的帮助。
      • 从来没有说过它是有效的,只是一种替代方法:-)
      【解决方案5】:

      如果 xp 级别不同,您可以使用array_flip。然后您可以使用 xp 作为索引来简单地访问级别编号:

      $levels = array_flip($lvl_correspondance);
      $lvl = $levels[15084];
      

      编辑:但也许一个函数会更好地获取两者之间的 xp 级别:

      function getLvlOf($xp) {
        // get the levels in descending order
        $levels = array_reverse($GLOBALS['lvl_correspondance'], true);
      
        foreach ($levels as $key => $value) {
          if ($xp >= $value)
            return $key;
        }
      
        // no level reached yet
        return 0;
      }
      

      【讨论】:

      • 如果关卡不存在,则为空。 OP 想要“最近”的值。
      • 不是查找,是两个级别之间的值
      • 只要确保值都是唯一的。来自php手册If a value has several occurrences, the latest key will be used as its values, and all others will be lost.
      • @Marc B:OP 说“返回 specific xp 的 lvl”。我对此给出了解决方案。在那之后,我编辑了一个我觉得更好的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2010-12-20
      • 1970-01-01
      • 2013-03-07
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 2020-06-03
      • 2011-09-23
      相关资源
      最近更新 更多