2010-04-06 10 views
6

tengo una matriz que tiene este aspecto:¿La manera más fácil de eliminar claves de una matriz 2D?

array(
    0 => array(
    'key1' => 'a', 
    'key2' => 'b', 
    'key3' => 'c' 
), 
    1 => array(
    'key1' => 'c', 
    'key2' => 'b', 
    'key3' => 'a' 
), 
    ... 
) 

Necesito una función para obtener una matriz que contiene sólo una (variable) número de teclas, es decir reduce_array (array ('key1', 'key3')) ; debería devolver:

array(
    0 => array(
    'key1' => 'a', 
    'key3' => 'c' 
), 
    1 => array(
    'key1' => 'c', 
    'key3' => 'a' 
), 
    ... 
) 

¿Cuál es la forma más fácil de hacer esto? Si es posible sin ninguna función auxiliar adicional como array_filter o array_map, mis compañeros de trabajo ya se quejan de que use demasiadas funciones.

La matriz de origen siempre tendrá las claves dadas, por lo que no es necesario verificar la existencia.

Puntos de bonificación si los valores son únicos (las claves siempre estarán relacionadas entre sí, lo que significa que si key1 tiene valor a, entonces la otra clave siempre tendrá el valor b).

Mi solución actual, que funciona, pero es bastante torpe (incluso el nombre es horrible, pero no puede encontrar uno mejor):

function get_unique_values_from_array_by_keys(array $array, array $keys) 
{ 
     $result = array(); 
     $found = array(); 

     if (count($keys) > 0) 
     { 
       foreach ($array as $item) 
       { 
         if (in_array($item[$keys[0]], $found)) continue; 
         array_push($found, $item[$keys[0]]); 
         $result_item = array(); 
         foreach ($keys as $key) 
         { 
           $result_item[$key] = $item[$key]; 
         } 
         array_push($result, $result_item); 
       } 
     } 
     return $result; 
} 

Adición:
PHP versión 5.1.6 es.

Respuesta

6

Si a sus compañeros de trabajo no les gusta array_filter o array_map, esa es su falta de educación y gusto. Si bien no aconsejo quemar puentes en el trabajo, con frecuencia son la mejor manera de resolver un problema.

 
function reduce_array($array, $keys) { 
    $keys_map = array_fill_keys($keys, true); 
    return array_map(function ($subarray) use ($keys) { 
    return array_intersect_key($subarray, $keys_map); 
    }, $array); 
} 

(Nota: las funciones anónimas que uso anteriormente sólo están disponibles en PHP> = 5.3, por lo que probablemente no se pueden utilizar)

Si debe hacerlo sin array_map y funciones anónimas:

 
function reduce_array($array, $keys) { 
    $ret = array(); 
    $keys_map = array_fill_keys($keys, true); 
    foreach ($array as $subarray) { 
    array_push($ret, array_intersect_key($subarray, $keys_map)); 
    } 
    return $ret; 
} 

explicar brevemente: en primer lugar, yo uso array_fill_keys para activar las teclas de una matriz de enteros indexados a una matriz de cadenas indexados (el valor que le doy, true, en realidad no importa aquí). Esto lo hace una entrada adecuada para array_intersect_key, que hará la reducción exacta que está buscando.

+0

muy agradable, @jemfinch. – karim79

+0

Muy buena solución, parece justo lo que necesitaba, pero esperaré otras soluciones posibles antes de aceptar. – dbemerlin

1

Solo usando la función in_array(). Número de letras que se puede reducir, pero lo dejaremos legible:

function reduce_array($array, $keys) { 
    $res=array(); // Our result array 
    foreach($array as $v1){ // Loop thru original array 
     $t1=array(); // Our new inner array 
     foreach($v1 as $k2=>$v2){ // Loop thru original inner array 
      if(in_array($k2,$keys)) $t1[$k2]=$v2; //If inside inner array store 
     } 
     $res[]=$t1; //Add to result array 
    } 
    return($res); 
} 

estoy con ganas de deshacerse de la in_array() la función, así, pero realmente hay que hacer algún trabajo;)

Cuestiones relacionadas