2012-09-10 85 views
19

理论上的问题可能没有任何意义,但仍然可能有一个聪明的答案。只返回键的PHP foreach

我想遍历数组,并获得它的键和他们的东西。我做什么一个简单的例子:现在

foreach($array as $key => $value) { 
    $other_array[$key] = 'something'; 
} 

PHP Mess Detector尖叫说$value在此范围内使用。因此,我想这可能不是访问我的arraykeys的最佳方式。

任何想法如何做到这一点,而不会不必要地从我的array中取出values?它是否有任何显着的性能影响...或者我只是偏执狂,应该继续而不浪费任何时间愚蠢的问题:)。

+0

这很正常。但是U可以使用这个:$ keys = array_key($ array); foreach($ key为$ key){ $ other_array [$ key] ='something'; } – Sergey

+0

您可以针对下列情况抑制混乱检测器的警告: http://phpmd.org/documentation/suppress-warnings.html – wkm

回答

37

你可以做这样的事情

foreach(array_keys($array) as $key) { 
// do your stuff 
} 

这将使的foreach叠代由来自按键阵列您数组而不是实际的数组。请注意,从性能角度来看,这可能不会更好。

+0

我相信array_keys()会在这里被每次迭代调用,所以它可能不是最聪明的举动? –

+0

没有从我记得数组进入foreach,如果评估一次。就像* foreach(数组(“a”,“b”,“c”)为$字母)*不会在每次迭代时创建一个新数组。如果这是不正确的,那么确定,在foreach之前创建一个$ keys变量......你有没有任何参考指向foreach在每次迭代中评估数组的事实? – inquam

+2

从我可以看到foreach()是使用迭代器实现的,因此只调用一次返回数组的函数。然后它使用指向现有结果集的迭代器继续每个项目。因此,对于* foreach(array_keys()... * – inquam

5

是的,有做这样一个更快的方法:http://php.net/manual/en/function.array-keys.php

+0

+1因为在钱上,但是询问给出了一个很好的例子,所以他得到了好处; ) – RandomWhiteTrash

+1

我不太确定创建一个包含初始数组的键(这是array_keys所做的)的新数组是* *更快*。但至少可以完成这项工作。 – inquam

+0

我还没有做基准测试,但我认为它比来自提问者的代码更快,其中也建立了一个新的数组。 array_keys()在内部以优化的方式(我希望)而不是使用脚本语言本身。 – LeJared

1

如果你想将所有键设置一定的价值,你可以做这样说:

$array = array(
     'foo'=> 'oldval1', 
     'bar'=> 'oldval2', 
     'baz'=> 'oldval3' 
); 

$other_array = array_fill_keys(array_keys($array), 'something'); 
print_r($other_array); 

这将产生:

Array 
(
    [foo] => something 
    [bar] => something 
    [baz] => something 
) 
+0

+1这个想法虽然这不是我想到的 - 例子过于简单:)。无论如何谢谢 - 学习新东西:) – RandomWhiteTrash

5

,请忽略此消息。

在PHP中,您使用foreach的方式是最快的。这是对的,你应该避免未使用的变量,但在这种情况下,你无法避免它,而不会失去一些性能。

E.g. foreach(array_keys($arr) as $key)foreach($arr as $key => $notUsed)慢大约50%到60%

此问题的phpmd已经报告here,并且还有一个拉动请求here

直到phpmd更新,你也可以(在我的情况线123)使用this little hack

在文件/src/main/php/PHPMD/Rule/UnusedLocalVariable.php的方法collectVariables(..)更换

if ($this->isLocal($variable)) 

通过

if ($this->isLocal($variable) && !($this->isChildOf($variable, 'ForeachStatement') && $variable->getName() === '$notUsed')) 

这将从报告中停止phpmd $notUsed任意位置 ach循环。

0

循环,以避免一段时间的foreach。

$a = ['1','A','B','12','ui']; 

while(true) { sleep(1); 
    $b = next($a) ? current($a): reset($a); 
    echo key($a) , ':' , $b , PHP_EOL; 
}