2012-02-02 6 views
5

Ho un array con chiavi e valori. Ogni valore è un numero intero. Ho un altro array con le stesse chiavi. Come posso sottrarre tutti i valori per le chiavi corrispondenti? Inoltre potrebbero esserci chiavi che non si verificano nel secondo array ma entrambi gli array hanno la stessa lunghezza. Se c'è una chiave nell'array 2 che non è presente nell'array 1, il suo valore dovrebbe essere invariato. Se c'è una chiave nel primo array che non è nel secondo dovrebbe essere gettato via. Come lo faccio? C'è una funzione integrata per questo?PHP sottrarre i valori dell'array

Se vorrei scrivere uno script che sarebbe una sorta di ciclo for in questo modo:

$arr1 = array('a' => 1, 'b' => 3, 'c' => 10); 
$arr2 = array('a' => 2, 'b' => 1, 'c' => 5); 
$ret = array(); 
foreach ($arr1 as $key => $value) { 
    $ret[$key] = $arr2[$key] - $arr1[$key]; 
} 
print_r($ret); 
/* 
should be: array('a' => 1, 'b' => -2, 'c' => -5) 
*/ 

non ho aggiunto l'occasione qui la chiave è in un array e non nell'altra.

+3

Sei sulla buona strada ... Penso che con un piccolo sforzo raggiungerai il tuo obiettivo. –

risposta

16

si poteva evitare il foreach utilizzando le funzioni di array se tu fossi così inclinato.

La chiusura fornita a array_mapdocs di seguito sottrarrà ogni valore $arr1 da ogni corrispondente $arr2. Purtroppo array_map non mantiene le chiavi quando si utilizza più di un array di input, così abbiamo usare array_combinedocs per unire i risultati sottratti di nuovo in un array con le chiavi originali:

$arr1 = array('a' => 1, 'b' => 3, 'c' => 10); 
$arr2 = array('a' => 2, 'b' => 1, 'c' => 5); 

$subtracted = array_map(function ($x, $y) { return $y-$x; } , $arr1, $arr2); 
$result  = array_combine(array_keys($arr1), $subtracted); 

var_dump($result); 

UPDATE

ero interessato a come l'array funziona in modo simile rispetto ad un foreach semplice, quindi ho messo a confronto entrambi usando Xdebug. Ecco il codice di prova:

$arr1 = array('a' => 1, 'b' => 3, 'c' => 10); 
$arr2 = array('a' => 2, 'b' => 1, 'c' => 5); 

function arrayFunc($arr1, $arr2) { 
    $subtracted = array_map(function ($x, $y) { return $y-$x; } , $arr1, $arr2); 
    $result  = array_combine(array_keys($arr1), $subtracted); 
} 

function foreachFunc($arr1, $arr2) { 
    $ret = array(); 
    foreach ($arr1 as $key => $value) { 
    $ret[$key] = $arr2[$key] - $arr1[$key]; 
    } 
} 

for ($i=0;$i<10000;$i++) { arrayFunc($arr1, $arr2); } 
for ($i=0;$i<10000;$i++) { foreachFunc($arr1, $arr2); } 

Come si è visto, utilizzando il ciclo foreach è un ordine di grandezza più veloce di compiere la stessa operazione utilizzando funzioni di matrice. Come potete vedere dall'immagine sottostante di KCachegrind, il metodo della funzione array richiedeva quasi l'80% del tempo di elaborazione nel codice sopra, mentre la funzione foreach richiedeva meno del 5%.

enter image description here

La lezione qui: a volte le funzioni di matrice più semantiche (? Sorprendentemente) può essere inferiore prestazioni-saggio ad un buon circuito vecchio stile in PHP. Certo, dovresti sempre scegliere l'opzione più leggibile/semantica; micro-ottimizzazioni come questa non sono giustificate se rendono il codice più difficile da capire per sei mesi lungo la strada.

+0

Nota che ho usato ** PHP 5.4RC6 ** con una CPU AMD64 2.2Ghz per questo test – rdlowrey

+0

Un'altra cosa: ho eseguito il test più volte e ho ricevuto risultati simili in ogni iterazione successiva. – rdlowrey

+0

Inoltre, dovrai aggiungere del codice extra per verificare che le chiavi in ​​'$ arr' e' $ arr2' corrispondano, come menzionato nella domanda - questo è molto più facile da fare con 'foreach'. – Izkata

0
foreach ($arr2 as $key => $value) { 
    if(array_key_exists($key, $arr1) && array_key_exists($key, $arr2)) 
     $ret[$key] = $arr2[$key] - $arr1[$key]; 
} 
0

PHP non offre operazioni matematiche vettorializzate. Vorrei attenermi al tuo attuale approccio all'utilizzo di un ciclo.

In primo luogo, vorrei ottenere l'insieme delle chiavi di matrice per ogni matrice. (Vedere la funzione array_keys). Quindi, intersecarli. Ora avrai le chiavi comuni a ciascun array. (Dai un'occhiata alla funzione array_intersect). Infine, continua. È un approccio leggibile e semplice.

Infine, si potrebbe dare un'occhiata a una biblioteca, come ad esempio Math_Vector: http://pear.php.net/package/Math_Vector