2016-07-05 110 views
0

正如標題的價值觀說我得到陣列看起來像這樣:合併嵌套數組

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) 

如果源和目標都是一樣的我想這個陣列中創建1個值。例如

Insteed這個:

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) 

我會想

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) 

我的想法來實現這一點:

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

    } 
} 

這似乎是合併,但只有2個值,它不刪除舊值,以便:

我有一樣的東西:

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) 

所以它合併了Gilauri和Janin,但沒有將Morrison,David添加到官員陣列,還添加了Gilauri,Irakli和Janin,Neil在這個數組中添加了不應該添加的單獨行。

回答

2

請注意,array_splice每次執行時都會重新鍵入數組。從文檔:

請注意,輸入中的數字鍵不會被保留。

I.e. 在$array = [0 => 1, 1 => 2, 2 => 3]將導致[0 => 1, 1 => 3]

因此,當您使用for循環進行迭代時,您的索引將爲每個已刪除的數組元素指向比以前更遠的一個條目。

要按索引刪除而不更換密碼,請使用unset($edges[$j])而不是array_splice()

可選地使用一個foreach環路(通過參考實際循環操作,而不是在一個副本):

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

但是我推薦unset()替代,因爲它的速度要快得多(array_splice總是完全再現了陣列)。

+0

這真的是對OP代碼問題的一個很好的解釋。 –

+0

@bwoebi謝謝你,像魅力一樣工作。我很高興我至少在某種程度上接近它的工作。 – Higeath

2

這與其他問題類似,您可以通過將子數組中的鍵用作合併結果中的鍵來解決此問題。這有點不同,因爲您需要使用多個鍵來確定應合併哪些記錄。

我會建議通過連接兩個鍵來完成它。

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

如果你不喜歡的組合鍵,你可以做array_values($merged)之後,回到普通數字鍵。

+0

雖然這並不能解釋他做錯了什麼(看我的回答),但這是很好的建議; +1。 – bwoebi

+0

@bwoebi謝謝!我喜歡使用這種方法來解決這類問題,因爲它只需要通過一個相當簡單的輸入數組。 –

+0

@ Don'tPanic謝謝你的幫助,這個解決方案也很棒! – Higeath