2010-04-06 3 views
6

Ich habe ein Array, das wie folgt aussieht:Der einfachste Weg, um Keys aus einem 2D-Array zu entfernen?

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

Ich brauche eine Funktion zu bekommen ein Array mit nur eine (variable) Anzahl der Tasten, das heißt reduce_array (array ('key1', 'key3')) ; sollte zurück:

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

Was ist der einfachste Weg, dies zu tun? Wenn möglich ohne zusätzliche Hilfsfunktionen wie array_filter oder array_map, da sich meine Mitarbeiter bereits über zu viele Funktionen beschweren.

Das Quell-Array hat immer die angegebenen Schlüssel, so dass es nicht erforderlich ist, die Existenz zu überprüfen.

Bonuspunkte, wenn die Werte eindeutig sind (die Schlüssel stehen immer zueinander in Beziehung, dh wenn Schlüssel1 den Wert a hat, haben die anderen Schlüssel immer den Wert b).

Meine aktuelle Lösung, die aber funktioniert, ist ziemlich ungeschickt (auch der Name schrecklich ist, aber keine besseren finden):

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

Zusatz:
PHP Version ist 5.1.6.

Antwort

6

Wenn Ihre Kollegen array_filter oder array_map nicht mögen, ist das der Mangel an Ausbildung und Geschmack. Während ich brennende Brücken bei der Arbeit nicht rate, sind sie oft der beste Weg, um ein Problem zu lösen.

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

(Hinweis: die anonyme Funktionen, die ich oben verwenden, sind nur in PHP> = 5.3 zur Verfügung, so dass Sie wahrscheinlich nutzen sie nicht)

Wenn Sie es ohne array_map und anonyme Funktionen tun müssen:

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

kurz zu erläutern: erstens, ich array_fill_keys Schlüssel aus einer ganzen Zahl indexierten Array in einen String-Array indiziert drehen (der Wert, den ich geben, true, ist nicht wirklich wichtig hier). Dies macht es geeignet für array_intersect_key, die die genaue Reduktion tun, die Sie suchen.

+0

sehr schön, @jemfinch. – karim79

+0

Sehr gute Lösung, scheint genau das zu sein, was ich brauchte, aber ich werde auf andere mögliche Lösungen warten, bevor ich akzeptiere. – dbemerlin

1

Nur mit der Funktion in_array(). Zeichenanzahl reduziert werden, aber wir werden es lesbar lassen:

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

Ich bin Juckreiz als auch, um loszuwerden, die in_array() Funktion, aber ich muss wirklich etwas Arbeit tun;)