2013-06-20 256 views
0

我需要查看Array1,從Array2中查找任何匹配序列,並更新Array1中相應的子數組。PHP - 在嵌套數組2中查找嵌套數組1

我以前曾就類似問題提供過幫助; Find array in array, in sequence

以前的解決方案非常有效 - 但這次我正在處理更復雜的數據,而且我需要更新Haystack數組(而不是簡單地返回匹配項)。

陣列1:乾草堆

Array ( 
    [0] => Array ([v1] => aa [v2] =>) 
    [1] => Array ([v1] => bb [v2] =>) 
    [2] => Array ([v1] => cccc [v2] =>) 
    [3] => Array ([v1] => bb [v2] =>) 
    [4] => Array ([v1] => aa [v2] =>) 
    [5] => Array ([v1] => bb [v2] =>) 
    [6] => Array ([v1] => cccc [v2] =>) 
    [7] => Array ([v1] => bb [v2] =>) 
) 

陣列2:針

Array ( 
    [0] => Array ([aa] => nnnn [bb] => nnn [cccc] =>n) 
    [1] => Array ([aa] => ddd [bb] => dd) 
) 

因此我應該找到在草堆 「AA BB CCCC」(針[0]),並更新該陣列成爲;

Array ( 
    [0] => Array ([v1] => aa [v2] => nnnn) 
    [1] => Array ([v1] => bb [v2] => nnn) 
    [2] => Array ([v1] => cccc [v2] => n) 
    [3] => Array ([v1] => bb [v2] =>) 
    [4] => Array ([v1] => aa [v2] =>) 
    [5] => Array ([v1] => bb [v2] =>) 
    [6] => Array ([v1] => cccc [v2] =>) 
    [7] => Array ([v1] => bb [v2] =>) 
) 

我有兩個版本的代碼是;

代碼版本1:

// cache array sizes 
$haystack_len = count($haystack); 
$needle_len = count($needle); 

// shortlist the possible starting keys 
$possible_keys = array_keys($haystack, $needle[0], true); 

$results = array(); 

foreach ($possible_keys as $index) { 
    // start searching 
    $i = $index; $j = 0; 
    while ($i < $haystack_len && $j < $needle_len) { 
     if ($haystack[$i] !== $needle[$j]) { 
      continue 2; // no match 
     } 
     ++$i; ++$j; 
    } 
    // match 
    $results[] = range($index, $index + $needle_len - 1); 
} 

print_r($results); 

和 代碼版本2:

function find_array_in_array($needle, $haystack) { 
    $keys = array_keys($haystack, $needle[0]); 
    $out = array(); 
    foreach ($keys as $key) { 
     $add = true; 
     $result = array(); 
     foreach ($needle as $i => $value) { 
      if (!(isset($haystack[$key + $i]) && $haystack[$key + $i] == $value)) { 
       $add = false; 
       break; 
      } 
      $result[] = $key + $i; 
     } 
     if ($add == true) { 
      $out[] = $result; 
     } 
    } 
    return $out; 
} 

但是,這些設計有平面陣列工作;

$haystack = array('a', 'b', 'a', 'b', 'c', 'c', 'a', 'b', 'd', 'c', 'a', 'b', 'a', 'b', 'c'); 
$needle = array('a', 'b', 'c'); 

相反,我需要它們與數組作爲每頂部(嵌套工作,並且針正在尋找匹配到針[鍵]草堆[陣列] [V1]

雖然我擺弄,並與前面的代碼faffed,我不能打敗它變成正確的形狀:( 我一直通過持續的foreach循環來訪問的事情,並採用與()等

foreach ($needlebox as $needles){ 
    foreach ($needles as $needlekey=>$needlevalue){ 
     foreach ($haystack as $haystackkey=>$haystackvalues){ 

      // insert above methods 

     } 
    } 
} 

但我想遇到以下問題; 1)Array2(Needles)is巨大的,相同的針出現多次? 2)我只得到一個匹配(即使陣列1包含與陣列2針n的多個匹配 - 它只發現一個)第一個或b)最後一個)3)它匹配無論順序/序列(我認爲我以某種方式破壞了代碼,並且它會匹配「cccc bb aa」,當Needles中的該順序不存在時(它代之以「aa bb cccc」)。

我已經花了2天的時間,我做錯了。

我已經嘗試使用這兩種解決方案(在foreach和對於方法)...但我不能讓任何一方的工作。

+1

這對我來說不是很清楚你想要達到什麼目的。你會使用所有的「針」還是隻使用一個特定的針(例如,g爲什麼你不在上面的例子中將「aa」設置爲「ddd」和「bb」設置爲「dd」)? – gkalpak

+0

@ExpertSystem - 對不起,如果不是很清楚。基本上,有一個大的嵌套數組(乾草堆),充滿了子數組。我需要從一組較小的數組中找到匹配項,並使用較小的子數組(針)來更新Haystack。 ::如果有幫助,可以考慮通過查看訂單和更新客戶地址等方案 - 我瀏覽客戶數據(乾草堆),並更新郵編(針)的匹配。希望更清楚。 – theclueless1

回答

1

如果我明白你是什麼正確試圖實現,你coul ð像這樣做(見代碼中的註釋):

/* Process one needle (look into haystack 
    and modify it accordingly) */ 
function processNeedle(&$haystack, $needle) { 
    $needleKeys = array_keys($needle); 
    $needleValues = array_values($needle); 
    $needleLen = count($needle); 
    $haystackLen = count($haystack); 

    /* Find indexes where a match begins */ 
    $matches = array(); 
    for ($i = 0; $i < ($haystackLen - $needleLen + 1); $i++) { 
     $match = true; 
     for ($j = 0; $j < $needleLen; $j++) { 
      if ($haystack[$i + $j]["v1"] != $needleKeys[$j]) { 
       $match = false; 
       break; 
      } 
     } 
     if ($match) { 
      $matches[] = $i; 
      $i += $needleLen - 1; 
     } 
    } 

    /* Do the actual replacement for all matches */ 
    forEach ($matches as $startIdx) { 
     for ($j = 0; $j < $needleLen; $j++) { 
      $haystack[$startIdx + $j]["v2"] = $needleValues[$j]; 
     } 
    } 
} 

還參見本short demo

+0

這看起來不錯(並且鏈接到頁面很棒)。我有gfot的問題是我被2個嵌套數組卡住了 - 唯一的辦法就是在一堆嵌套的foreach中使用這個代碼......是嗎? – theclueless1

+0

好吧 - 由於環境而稍微改編(在一個類中,必須添加一個foreach循環才能從對象中獲取針)......但它的工作原理!非常感謝@ExperSystem。 – theclueless1

+0

快速跟進...我已經調整它包含在現有的類中。當我經過大型乾草堆(1K物品)和很多針(5K)時,它需要約5秒...是預期的嗎?有沒有什麼明顯的方法來加速它,或者它是否與這種迭代(由於嵌套等)有關? ::再次,謝謝@ExpertSystem - 太棒了! – theclueless1