php arrays numbers integer subtraction

PHP resta valores de matriz



arrays numbers (3)

Tengo una matriz con claves y valores. Cada valor es un entero. Tengo otra matriz con las mismas teclas. ¿Cómo puedo restar todos los valores de las claves coincidentes? También puede haber claves que no aparecen en la segunda matriz, pero ambas tienen la misma longitud. Si hay una clave en la matriz 2 que no está presente en la matriz 1, su valor no se modificará. Si hay una clave en la primera matriz que no está en el segundo, debe descartarse. ¿Cómo lo hago? ¿Hay alguna función incorporada para esto?

Si escribiera un guión, sería una especie de ciclo de este tipo:

$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) */

No agregué la ocasión aquí, una clave está en una matriz y no en la otra.


PHP no ofrece operaciones matemáticas vectorizadas. Me quedaría con su enfoque actual de usar un bucle.

Primero, obtendría el conjunto de claves de matriz para cada matriz. (Ver la función array_keys ). Luego, interseccionalos. Ahora tendrá las claves comunes a cada matriz. (Eche un vistazo a la función array_intersect ). Por último, iterar. Es un enfoque fácil de leer.

Por último, puedes echar un vistazo a una biblioteca, como Math_Vector: http://pear.php.net/package/Math_Vector


Podrías evitar el foreach usando funciones de matriz si así lo deseas.

El cierre proporcionado a los documentos array_map continuación restará cada valor $arr1 de cada $arr2 correspondiente. Desafortunadamente array_map no conservará sus claves cuando use más de una matriz de entrada, entonces usaremos array_combine docs para fusionar los resultados restados a una matriz con las claves originales:

$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);

ACTUALIZAR

Estaba interesado en cómo se acercan las funciones de matriz en comparación con un foreach simple, por lo que comparé ambas utilizando Xdebug. Aquí está el código de prueba:

$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); }

Resulta que usar el ciclo foreach es un orden de magnitud más rápido que realizar la misma tarea usando funciones de matriz. Como puede ver en la siguiente imagen de KCachegrind callee, el método de la función de matriz requirió casi el 80% del tiempo de procesamiento en el código anterior, mientras que la función foreach requirió menos del 5%.

La lección aquí: a veces, las funciones de matriz más semántica (¿sorprendentemente?) Pueden ser inferiores en cuanto a rendimiento a un buen bucle pasado de moda en PHP. Por supuesto, siempre debe elegir la opción que sea más legible / semántica; Las micro-optimizaciones como esta no están justificadas si hacen que el código sea más difícil de entender seis meses después.


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