2012-09-10 12 views
19

Domanda teorica che forse non ha alcun senso ma ancora, forse c'è una risposta intelligente.foreach PHP che restituisce solo le chiavi

Voglio ripetere l'array e ottenere le sue chiavi e qualcosa con loro. Un rapido esempio di quello che faccio:

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

Ora, PHP Mess Detector urla che $value è inutilizzato in questo ambito. Quindi stavo pensando che forse questo non è il modo migliore per accedere a keys del mio array.

Qualche idea su come farlo senza estrarre inutilmente values dal mio array? Ha un impatto significativo sulle prestazioni ... o forse sono solo paranoico e dovrei continuare senza sprecare il tempo di nessuno con domande stupide :).

+0

È normale. Ma U può usare questo: $ keys = array_key ($ array); foreach ($ chiavi come $ chiave) { $ other_array [$ key] = 'something'; } – Sergey

+0

È possibile sopprimere gli avvisi del rilevatore di messaggi per istanze come queste: http://phpmd.org/documentation/suppress-warnings.html – wkm

risposta

37

Si potrebbe fare qualcosa di simile

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

che renderebbero il foreach iterare su un array composto dalle chiavi dal vostro matrice invece della matrice effettiva. Si noti che probabilmente non è meglio dal punto di vista delle prestazioni.

+0

Credo che array_keys() venga chiamato per ogni iterazione qui, quindi probabilmente non è la mossa più intelligente? –

+0

No, da quello che ricordo l'array che entra nel foreach se valutato una volta. Proprio come fare * foreach (array ("a", "b", "c") come $ letters) * non crea una nuova matrice su ogni iterazione. Se ciò non è corretto, assicurati di creare una variabile $ keys prima del foreach ... Hai qualche riferimento che faccia riferimento al fatto che foreach valuta l'array su ogni iterazione? – inquam

+2

Da quello che posso vedere foreach() è implementato usando gli iteratori e quindi chiama solo la funzione che restituisce una matrice una volta. Quindi utilizza l'iteratore che punta al set di risultati esistente per continuare con ciascun elemento. Quindi è perfettamente sicuro to * foreach (array_keys() ... * – inquam

5

Sì, c'è un modo più veloce per fare questo: http://php.net/manual/en/function.array-keys.php

+0

+1 per essere sul denaro ma l'inchiesta ha dato un bell'esempio in modo da ottenere il bottino; – RandomWhiteTrash

+1

Non sono sicuro che la creazione di un nuovo array contenente le chiavi dell'array iniziale (che è ciò che fa array_keys) sia * più veloce *. Ma almeno il lavoro è fatto. – inquam

+0

Non ho fatto benchmark, ma penso che sia più veloce del codice dall'interrogatore, che costruisce anche un nuovo array. array_keys() lo fa internamente in un modo ottimizzato (spero) piuttosto che usare il linguaggio di scripting stesso. – LeJared

1

Se si desidera impostare tutte le chiavi per certo valore solo si può fare in questo modo:

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

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

Questo produrrà:

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

+1 per l'idea, anche se non era quello che avevo in mente - l'esempio era troppo semplificato :). Grazie comunque - imparando qualcosa di nuovo :) – RandomWhiteTrash

5

ignorare questo messaggio.

In PHP il modo in cui è stato utilizzato foreach è il più veloce. È giusto che tu eviti le variabili inutilizzate, ma in questo caso non puoi evitarlo, senza perdere qualche prestazione.

E.g. foreach(array_keys($arr) as $key) è circa dal 50% al 60% più lento
rispetto a foreach($arr as $key => $notUsed).

Questo problema di phpmd è già segnalato here e c'è già una richiesta pull here.

Fino phpmd viene aggiornato è anche possibile utilizzare this little hack

Nel file /src/main/php/PHPMD/Rule/UnusedLocalVariable.php nel metodo collectVariables(..) (linea 123 nel mio caso) sostituire

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

da

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

Questa volontà stop phpmd dal report $notUsedovunque all'interno di una prua ach loop.

0

ciclo per evitare un foreach in un istante.

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

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