1

我试图根据另一个值找到 PHP 数组的最高键。

$values = array(0,0,50,100,200,400,800);

如果我说我有 125 的值,它应该返回 3。如果我有 400 到 799 之间的任何值,它应该返回 5。

$output = -1;
$input = 436;
$length = count($values);
for($i=1;$i<=$length;$i++){
    if($values[$i]<=$input) { $output++; }
}
// Returns 5

我可以遍历数组,但是有 100 个值,这会大大降低页面速度,因为每个用户每次页面加载使用了大约 20 次。有没有我缺少的特殊功能?或者我将不得不 foreach 数组?

数组总是有序的,永远不会改变。

4

2 回答 2

1

您可以使用array_flip()来做到这一点。

[ghoti@pc ~]$ php -r '$n=150; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
3
[ghoti@pc ~]$ php -r '$n=401; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
5
[ghoti@pc ~]$ php -r '$n=200; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
4
[ghoti@pc ~]$ php -r '$n=0; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
1

这是如何运作的?

让我们分解一下。

  • $n=0;我们的号码。
  • $a=array(0,0,50,100,200,400,800);我们的阵列。
  • $a[]=$n;我们将我们的号码添加到数组中......
  • sort($a);对事物进行排序以将我们的号码放在正确的位置...
  • $f=array_flip($a);然后我们用索引交换值,
  • print $f[$n]-1并返回我们添加的项目之前的项目的值(以前是索引)。

如果 $a 包含相同数字的多个条目,例如0在您的示例中,则可能会造成混淆。如果发生这种情况,您可能需要调整调整(-1在我的示例中),因为索引只能在数组中出现一次。(例如,如果0出现 3 次,你需要用 调整你的结果-2。这个调整可以添加额外的代码,但我相信你可以自己弄清楚那部分。:)

这避免了循环,但要小心 if $n=0

于 2012-10-17T01:30:33.910 回答
1

对不起,但是AFAIK你真的必须循环这个低谷。

如果数组是有序的,你可以找到第一个更高的索引,然后添加剩余的索引。


编辑:这是我用来基准测试的代码:

set_time_limit(0);

$a = array(0,0,50,100,200,400,800);
$a = array_merge(range(0, 100000), $a);

sort(a); // we need this since array_merge will not maintain the sequence

$result = array
(
    'testWithForeach' => 0,
    'testWithArrayFlip' => 0,
    'testWithArraySearch' => 0,
);

foreach (range(0, 1000, 10) as $n) // search values $n to try
{
    for ($i = 0; $i < 10; ++$i) // how many times to run each test
    {
        foreach (array_keys($result) as $test) // divide the CPU usage fairly (inner-most loop)
        {
            $start = microtime(true); call_user_func($test, $a, $n); $result[$test] += (microtime(true) - $start);
        }
    }
}

asort($result);

echo '<pre>';
print_r($result);
echo '</pre>';

function testWithForeach($a, $n)
{
    foreach ($a as $key => $value)
    {
        if ($value >= $n)
        {
            $result = $key; break;
        }
    }

    return $result;
}

function testWithArrayFlip($a, $n)
{
    $a[] = $n; sort($a); $a = array_flip($a); return ($a[$n] - 1);
}

function testWithArraySearch($a, $n)
{
    $a[] = $n; sort($a); return (array_search($n, $a) - 1);
}

所有方法都在相似的条件下运行,并且分布在 CPU 时间上。

我测试了$n从 0 到 1000 的所有值,使用 10 作为步长(总共 100)。

每个$n/ 方法组合运行了 10 次,我得到的结果是:

Array
(
    [testWithForeach] => 19.338931560516
    [testWithArraySearch] => 96.209128856659
    [testWithArrayFlip] => 133.85276961327
)

我尽量做到公平,实际运行时间可能会因$n其他条件而异。

于 2012-10-17T01:12:16.337 回答