2016-07-05 12 views
0

Wie der Titel schon sagt, ich Array suchen etwas wie diese:Merging Werte von verschachtelten Array

array (size=376) 
    0 => 
    array (size=3) 
     'source' => int 0 
     'target' => int 47 
     'officers' => 
     array (size=1) 
      0 => string 'PARKER, Thomas, Sir' (length=19) 
    1 => 
    array (size=3) 
     'source' => int 0 
     'target' => int 104 
     'officers' => 
     array (size=1) 
      0 => string 'STEVENS, Anne' (length=13) 
    2 => 
    array (size=3) 
     'source' => int 0 
     'target' => int 187 
     'officers' => 
     array (size=1) 
      0 => string 'PARKER, Thomas, Sir' (length=19) 
    3 => 
    array (size=3) 
     'source' => int 0 
     'target' => int 229 
     'officers' => 
     array (size=1) 
      0 => string 'GROTE, Byron' (length=12) 
    4 => 
    array (size=3) 
     'source' => int 0 
     'target' => int 244 
     'officers' => 
     array (size=1) 
      0 => string 'GROTE, Byron' (length=12) 
    5 => 
    array (size=3) 
     'source' => int 1 
     'target' => int 60 
     'officers' => 
     array (size=1) 
      0 => string 'BASON, John' (length=11) 
    6 => 
    array (size=3) 
     'source' => int 1 
     'target' => int 92 
     'officers' => 
     array (size=1) 
      0 => string 'HAUSER, Wolfhart, Dr' (length=20) 

Wenn Quelle und Ziel sind die gleichen I 1 Wert in diesem Array erstellen möchten, zum Beispiel

Insteed dafür:

5 => 
     array (size=3) 
      'source' => int 1 
      'target' => int 92 
      'officers' => 
      array (size=1) 
       0 => string 'BASON, John' (length=11) 
     6 => 
     array (size=3) 
      'source' => int 1 
      'target' => int 92 
      'officers' => 
      array (size=1) 
       0 => string 'HAUSER, Wolfhart, Dr' (length=20) 

ich möchte

5 => 
      array (size=3) 
       'source' => int 1 
       'target' => int 92 
       'officers' => 
       array (size=1) 
        0 => string 'BASON, John' (length=11) 
        1 => string 'HAUSER, Wolfhart, Dr' (length=20) 
erhalten

Meine Idee, dies zu erreichen:

for ($i = 0; $i < count($edges); $i++) { 
    for ($j = $i + 1; $j < count($edges); $j++) { 
     if($edges[$i]['source']==$edges[$j]['source']&&$edges[$i]['target']==$edges[$j]['target']){ 
      foreach($edges[$j]['officers'] as $officer){ 
       array_push($edges[$i]['officers'], $officer); 
      } 
      array_splice($edges, $j,1); 
     } 

    } 
} 

Es scheint aber nur 2 Werte verschmelzen zu werden, und es ist nicht die alten Werte zu löschen so:

Ich habe so etwas wie:

66 => 
    array (size=3) 
     'source' => int 24 
     'target' => int 103 
     'officers' => 
     array (size=2) 
      0 => string 'GILAURI, Irakli' (length=15) 
      1 => string 'JANIN, Neil' (length=11) 
    67 => 
    array (size=3) 
     'source' => int 24 
     'target' => int 103 
     'officers' => 
     array (size=1) 
      0 => string 'MORRISON, David' (length=15) 

Also es Gilauri und Janin merget aber Morrison, David zum Offiziersfeld nicht hinzugefügt und auch Gilauri, Irakli und Janin, Neil haben getrennte Reihe in diesem Feld, das nicht hinzugefügt werden sollte.

Antwort

2

Beachten Sie, dass array_splice das Array bei jeder Ausführung erneut eingibt. Aus der Dokumentation:

Beachten Sie, dass numerische Tasten in Eingabe nicht beibehalten werden.

I.e. auf $array = [0 => 1, 1 => 2, 2 => 3] wird in [0 => 1, 1 => 3] resultieren.

Wenn Sie also mit einer for-Schleife iterieren, zeigt Ihr Index einen weiteren Eintrag für jedes entfernte Array-Element an.

Verwenden Sie anstelle des array_splice(), um den Index ohne Neuschlüsselung zu entfernen.

Alternativ eine foreach Schleife verwenden (unter Bezugnahme auf die eigentliche Schleife und nicht auf einer Kopie zu arbeiten):

foreach ($edges as $i => &$edge) { 
    for ($j = $i + 1; $j < count($edges); $j++) { 
     if ($edge['source'] == $edges[$j]['source'] && $edge['target'] == $edges[$j]['target']) { 
      foreach ($edges[$j]['officers'] as $officer) { 
       array_push($edge['officers'], $officer); 
      } 
      array_splice($edges, $j, 1); 
     } 
    } 
} 

Aber ich empfehle die unset() Alternative, da es viel schneller ist (array_splice erschafft immer das Array vollständig).

+0

Das ist wirklich eine sehr gute Erklärung des Problems mit dem OP-Code. –

+0

@bwoebi danke, funktioniert wie ein Charme. Ich bin froh, dass ich zumindest kurz davor stand, es zum Laufen zu bringen. – Higeath

2

Dies ist vergleichbar mit anderen Problemen, bei denen Sie dies lösen können, indem Sie einen Schlüssel aus den Sub-Arrays als Schlüssel in Ihrem zusammengeführten Ergebnis verwenden. Es ist nur ein wenig anders, weil Sie mehr als einen Schlüssel verwenden müssen, um zu bestimmen, welche Datensätze zusammengeführt werden sollen.

Ich würde vorschlagen, es nur durch Verketten der beiden Schlüssel zu tun.

foreach ($your_array as $item) { 
    $k = "$item[source].$item[target]"; 
    if (isset($merged[$k])) { 
     $merged[$k]['officers'] = array_merge($merged[$key]['officers'], $item['officers']); 
    } else { 
     $merged[$k] = $item; 
    } 
} 

Und wenn Sie nicht den zusammengesetzten Schlüssel mögen, können Sie array_values($merged) nachher tun, um wieder auf Normal numerische Tasten zu bekommen.

+0

Während das nicht erklärt, was er falsch gemacht hat (siehe meine Antwort), ist das ein guter Rat; +1. – bwoebi

+0

@bwoebi Danke! Ich möchte diesen Ansatz für diese Art von Problem verwenden, da es nur einen ziemlich einfachen Durchlauf durch das Eingabearray erfordert. –

+0

@ Don'tPanic danke für die Hilfe diese Lösung funktioniert auch gut! – Higeath