代码之家  ›  专栏  ›  技术社区  ›  Pekka

从阵列反射范围中选取最近的值

  •  12
  • Pekka  · 技术社区  · 14 年前

    $rebates = array(
       1 => 0,
       3 => 10,
       5 => 25,
      10 => 35)
    

    也就是说,对于一个或两个项目,你不会得到回扣;对于3+项目,你会得到10%,对于5+项目,你会得到20%,对于10+35%等等。

    优雅的 7 ?

    显然,这可以用一个简单的循环来解决:这不是我要找的。我感兴趣的是是否有一个核心数组或其他功能,我不知道,可以做得更优雅。

    我将给这个被接受的答案200英镑的奖金,但显然,我得等上24小时才能做到。问题解决了。

    4 回复  |  直到 14 年前
        1
  •  16
  •   salathe    14 年前

    这是另一个,同样不短。

    $percent = $rebates[max(array_intersect(array_keys($rebates),range(0,$items)))];
    

    max )介于两者之间 0 $items .

        2
  •  5
  •   NikiC    14 年前

    我认为上面的一行解决方案并不是很优雅或可读。那么,为什么不使用一些第一眼就能被人真正理解的东西呢?

    $items = NUM_OF_ITEMS;
    $rabate = 0;
    foreach ($rabates as $rItems => $rRabate) {
        if ($rItems > $items) break;
        $rabate = $rRabate;
    }
    

    好吧,我知道,你不需要简单循环的解决方案。但是这个呢:

    while (!isset($rabates[$items])) {
        --$items;
    }
    $rabate = $rabates[$items];
    

    还是挺直截了当的,不过短一点。我们能再短一点吗?

    for (; !isset($rabates[$items]); --$items);
    $rabate = $rabates[$items];
    

    我们已经接近一条线了。所以让我们做一点欺骗:

    for (; !isset($rabates[$items]) || 0 > $rabate = $rabates[$items]; --$items);
    

    这比其他答案中的所有方法都要短。它只有一个缺点:它改变了 $items 以后你可能还需要。所以我们可以:

    for ($i = $items; !isset($rabates[$i]) || 0 > $rabate = $rabates[$i]; --$i);
    

    又少了一个角色 $项

    尽管我认为最后两个版本已经太老套了。最好坚持这一点,因为它既简短又容易理解:

    for ($i = $items; !isset($rabates[$i]); --$i);
    $rabate = $rabates[$i];
    
        3
  •  2
  •   David Mårtensson    14 年前

    这可能在不更改折扣数组的情况下工作。

    但是数组必须以另一种方式构造才能工作

    $rebates = array(
       3 => 0,      //Every number below this will get this rebate
       5 => 10,
       10 => 25,
      1000 => 35);  //Arbitrary large numer to catch all
    
    $count = $_REQUEST["count"];
    
    $rv = $rebates[array_shift(array_filter(array_keys($rebates), function ($v) {global $count; return $v > $count;}))];
    
    echo $rv;
    

    http://empirium.dnet.nu/arraytest.php?count=5
    http://empirium.dnet.nu/arraytest.php?count=10

        4
  •  1
  •   Mark Baker    14 年前

    到目前为止我所能做到的最好:

    $testValue = 7;
    array_walk( $rebates, function($value, $key, &$test) { if ($key > $test[0]) unset($test[1][$key]); } array($testValue,&$rebates) );
    

    也许有人可以在此基础上丢弃数组中较低的条目。

    目前没有5.3.3可供使用,因此没有使用匿名函数进行测试,但在使用标准回调函数时可以工作(尽可能工作)。

    编辑

    $testValue = 7;
    array_walk( $rebates, function($value, $key, &$test) { if ($key > $test[0]) unset($test[1][$key]); } array($testValue,&$rebates) );
    array_walk( array_reverse($rebates,true), function($value, $key, &$test) { if ($key < $test[0]) unset($test[1][$key]); } array(array_pop(array_keys($rebates)),&$rebates) );
    

    现在,$rebates数组只包含一个元素,是原始$rebates数组的最高断点键,该数组的键值低于$testValue。

    推荐文章