2012-10-04 7 views
18

Wie kann ich eine tiefe Erweiterung eines mehrdimensionalen assoziativen Arrays (für die Verwendung mit decodierten JSON-Objekten) tun. Ich brauche die PHP-Entsprechung von jQuery's $.extend(true, array1, array2) mit Arrays anstelle von JSON und in PHP.PHP Deep Extend Array

Hier ist ein Beispiel dafür, was ich brauche

$array1 = ('1'=> ('a'=>'array1a', 'b'=>'array1b')); 
$array2 = ('1'=> ('a'=>'array2a', 'c'=>'array2b')); 

$array3 = array_extend($array1, $array2); 

//$array3 = ('1'=> ('a'=>'array2a', 'b'=>'array1b', 'c'=>'array2b')) 

Beachten Sie, wie array2 Überschreibungen Array1 wenn es denselben Wert hat (wie, wie Erweiterung von Klassen funktioniert)

(array_merge_recursive nicht die gleiche Sache zu tun haben scheinen)
+0

Warum nicht array_merge? – Dev

+2

Wenn Sie PHP 5.3.0+ haben, können Sie ['array_replace_recursive'] (http://www.php.net/manual/en/function.array-replace-recursive.php) verwenden, was genau das tut, was Sie brauchen. – Sathvik

+0

Ich hatte noch keine Zeit, alle Antworten zu überprüfen, aber array_replace_recursive scheint definitiv der einfachste Weg, dies zu erreichen. Willst du es als Antwort schreiben und ich akzeptiere? –

Antwort

18

Wenn Sie PHP 5.3.0+ haben, können Sie array_replace_recursive verwenden, die genau das tut, was Sie brauchen:

array_replace_recursive() ersetzt die Werte von array1 mit den gleichen Werte aus allen die folgenden Arrays. Wenn ein Schlüssel aus dem ersten Array im zweiten Array vorhanden ist, wird sein Wert vom zweiten Array durch den Wert ersetzt. Wenn der Schlüssel im zweiten Array und nicht im ersten Array vorhanden ist, wird er im ersten Array erstellt. Wenn ein Schlüssel nur im ersten Array existiert, wird er so belassen wie er ist. Wenn mehrere Arrays als Ersatz übergeben werden, werden sie nacheinander verarbeitet, wobei das spätere Array die vorherigen Werte überschreibt.

1

von array_merge docs Genommen:

function array_extend($a, $b) { 
    foreach($b as $k=>$v) { 
     if(is_array($v)) { 
      if(!isset($a[$k])) { 
       $a[$k] = $v; 
      } else { 
       $a[$k] = array_extend($a[$k], $v); 
      } 
     } else { 
      $a[$k] = $v; 
     } 
    } 
    return $a; 
} 
+4

Dies sollte Wiki Post sein –

+0

@Mihai Iorga Quick Frage Wie machst du einen Wiki-Post ??? – Baba

+1

@Baba Während des Bearbeitens/Postings können Sie irgendwo "Community" überprüfen. – Yoshi

0

Mit ein wenig googeln ich diesen gefunden:

/** 
* jquery style extend, merges arrays (without errors if the passed values are not arrays) 
* 
* @return array $extended 
**/ 
function extend() { 
    $args = func_get_args(); 
    $extended = array(); 
    if(is_array($args) && count($args)) { 
     foreach($args as $array) { 
      if(is_array($array)) { 
       $extended = array_merge($extended, $array); 
      } 
     } 
    } 
    return $extended; 
} 

extend($defaults, $new_options); 
1

Dies könnte das sein, was Sie suchen:

function array_extend(&$result) { 
    if (!is_array($result)) { 
    $result = array(); 
    } 

    $args = func_get_args(); 

    for ($i = 1; $i < count($args); $i++) { 
    // we only work on array parameters: 
    if (!is_array($args[$i])) continue; 

    // extend current result: 
    foreach ($args[$i] as $k => $v) { 
     if (!isset($result[$k])) { 
     $result[$k] = $v; 
     } 
     else { 
     if (is_array($result[$k]) && is_array($v)) { 
      array_extend($result[$k], $v); 
     } 
     else { 
      $result[$k] = $v; 
     } 
     } 
    } 
    } 

    return $result; 
} 

Verbrauch:

$arr1 = array('a' => 1, 'b' => 2, 'c' => 3); 
$arr2 = array('b' => 'b', 'd' => 'd'); 
array_extend($arr1, $arr2); 
print_r($arr1); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd') 

// or, to create a new array and leave $arr1 unchanged use: 
array_extend($arr3, $arr1, $arr2); 
print_r($arr3); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd') 

// or, use the return value: 
print_r(array_extend($arr1, $arr2)); // but this will also modify $arr1 
0

ich hier denke, ist die richtige Antwort, denn:

  • Ihre Antwort habe einen Fehler mit der Warnung:

    Warnung: Kann nicht einen skalaren Wert als Array in verwenden ...

Da ein $ nicht immer ein Array ist und Sie ein $ [$ k].

  • array_merge_recursive in die Tat Arrays verschmelzen, aber es wandelt Werte mit Nachschlüssel eher auf Arrays als den Wert in dem ersten Array mit dem doppelten Wert in dem zweiten Feld zu überschreiben, wie array_merge tut.

  • andere Antworten sind nicht rekursiv oder nicht einfach.

So, hier ist meine Antwort: Ihre Antwort ohne Fehler:

function array_extend(array $a, array $b) { 
    foreach($b as $k=>$v) { 
     if(is_array($v)) { 
      if(!isset($a[$k])) { 
       $a[$k] = $v; 
      } else { 
       if(!is_array($a[$k]){ 
        $a[$k]=array(); 
       } 
       $a[$k] = array_extend($a[$k], $v); 
      } 
     } else { 
      $a[$k] = $v; 
     } 
    } 
    return $a; 
} 

Und meine Antwort mit ternären Operator:

function array_extend(array $a, array $b){ 
    foreach($b as $k=>$v) 
      $a[$k] = is_array($v)&&isset($a[$k])? 
       array_extend(is_array($a[$k])? 
         $a[$k]:array(),$v): 
       $v; 
    return $a; 
} 

Edit: Und ein Bonus eines mit vielen Arrays Sie wollen:

function array_extend(){ 
    $args = func_get_args(); 
    while($extended = array_shift($args)) 
      if(is_array($extended)) 
        break; 
    if(!is_array($extended)) 
      return FALSE; 
    while($array = array_shift($args)){ 
     if(is_array($array)) 
       foreach($array as $k=>$v) 
         $extended[$k] = is_array($v)&&isset($extended[$k])? 
          array_extend(is_array($extended[$k])? 
            $extended[$k]:array(),$v): 
          $v; 
    } 
    return $extended; 
} 
2

Ich benutze dies in der gleichen So benutze ich angular.extend (dst, src) und jQuery.extend().

function extend($base = array(), $replacements = array()) { 
    $base = ! is_array($base) ? array() : $base; 
    $replacements = ! is_array($replacements) ? array() : $replacements; 

    return array_replace_recursive($base, $replacements); 
} 

Beispiel:

Si() ist ein Dienstprogramm Sanitize Funktion, die ein Array $ _POST oder $ _GET und gibt packt.

 $s = extend(array(
      'page' => 1, 
      'take' => 100, 
      'completed' => 1, 
      'incomplete' => 1, 
     ), si()); 
1

Sie verwenden sollten: https://github.com/appcia/webwork/blob/master/lib/Appcia/Webwork/Storage/Config.php#L64

/** 
* Merge two arrays recursive 
* 
* Overwrite values with associative keys 
* Append values with integer keys 
* 
* @param array $arr1 First array 
* @param array $arr2 Second array 
* 
* @return array 
*/ 
public static function merge(array $arr1, array $arr2) 
{ 
    if (empty($arr1)) { 
     return $arr2; 
    } else if (empty($arr2)) { 
     return $arr1; 
    } 

    foreach ($arr2 as $key => $value) { 
     if (is_int($key)) { 
      $arr1[] = $value; 
     } elseif (is_array($arr2[$key])) { 
      if (!isset($arr1[$key])) { 
       $arr1[$key] = array(); 
      } 

      if (is_int($key)) { 
       $arr1[] = static::merge($arr1[$key], $value); 
      } else { 
       $arr1[$key] = static::merge($arr1[$key], $value); 
      } 
     } else { 
      $arr1[$key] = $value; 
     } 
    } 

    return $arr1; 
}