2012-09-10 18 views
19

Pregunta teórica que quizás no tiene ningún sentido, pero aún así, tal vez haya una respuesta inteligente.PHP foreach que solo devuelve claves

Quiero iterar a través de la matriz y obtener sus claves y algo con ellos. Un ejemplo rápido de lo que hago:

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

Ahora, PHP Mess Detector$value grita que no se usa en este ámbito. Por lo tanto, estaba pensando que quizás esta no es la mejor manera de acceder al keys de mi array.

¿Alguna idea de cómo hacerlo sin quitar innecesariamente values de mi array? ¿Tiene algún impacto significativo en el rendimiento ... o tal vez estoy siendo paranoico y debería continuar sin perder el tiempo de nadie con preguntas estúpidas :).

+0

Es normal. Pero U puede usar esto: $ keys = array_key ($ array); foreach ($ claves as $ key) { $ other_array [$ key] = 'algo'; } – Sergey

+0

Puede suprimir las advertencias del detector de mess para casos como estos: http://phpmd.org/documentation/suppress-warnings.html – wkm

Respuesta

37

que podría hacer algo como esto

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

Eso haría que el foreach iterar sobre una matriz que consiste de las claves de su matriz en lugar de la matriz real. Tenga en cuenta que, sin embargo, probablemente no sea mejor desde el punto de vista del rendimiento.

+0

Creo que se llamaría a array_keys() para cada iteración aquí, por lo que probablemente no sea el movimiento más inteligente. –

+0

No de lo que recuerdo la matriz que entra en el foreach si se evalúa una vez. Al igual que hacer * foreach (matriz ("a", "b", "c") como $ letras) * no crea una nueva matriz en cada iteración. Si eso es incorrecto, entonces seguro, cree una variable $ keys antes del foreach ... ¿Tiene alguna referencia que apunte al hecho de que foreach evalúa la matriz en cada iteración? – inquam

+2

Según lo que puedo ver, foreach() se implementa mediante iteradores y, por lo tanto, solo llama a la función que devuelve una matriz una vez. Luego usa el iterador que apunta al conjunto de resultados existente para continuar con cada elemento. Por lo tanto, es perfectamente seguro para * foreach (array_keys() ... * – inquam

5

Sí, hay una manera más rápida de hacer esto: http://php.net/manual/en/function.array-keys.php

+0

+1 por estar en el dinero pero inquam dio un buen ejemplo para que consiga el botín;) – RandomWhiteTrash

+1

No estoy seguro de que crear una nueva matriz que contenga las claves de la matriz inicial (que es lo que hace array_keys) sea * más rápido *. Pero al menos es el trabajo hecho. – inquam

+0

No he hecho benchmarks, pero creo que es más rápido que el código del cuestionario, que también crea una nueva matriz. array_keys() lo hace internamente de forma optimizada (espero) en lugar de utilizar el lenguaje de scripts en sí. – LeJared

1

Si desea establecer todas las claves de cierto valor que sólo puede hacerlo de esta manera:

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

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

Esto producirá:

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

+1 por la idea, aunque eso no era lo que tenía en mente, por ejemplo, fue demasiado simplista :). Gracias de todos modos, aprendiendo algo nuevo :) – RandomWhiteTrash

5

simplemente ignorar este mensaje.

En PHP, la forma en que usaste foreach es la más rápida. Es correcto, que debe evitar las variables no utilizadas, pero en este caso no puede evitarlo, sin perder rendimiento.

E.g. foreach(array_keys($arr) as $key) es aproximadamente 50% a 60% más lento
que foreach($arr as $key => $notUsed).

Este número de phpmd ya se ha notificado here y también existe una solicitud de extracción here.

Hasta phpmd se actualiza también se puede utilizar this little hack

En el archivo /src/main/php/PHPMD/Rule/UnusedLocalVariable.php en el método collectVariables(..) (línea 123 en mi caso) reemplazar

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

por

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

Esta voluntad dejar de phpmd de informar $notUseden cualquier parte dentro de una parte delantera Ach Loops.

0

loop para evitar un foreach por un tiempo.

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

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