PHP - 在嵌套的array2中查找嵌套的array1

时间:2013-06-20 18:55:55

标签: php arrays inorder

我需要查看Array1,从Array2中找到任何匹配的序列,并更新Array1中相应的子数组。

我以前在类似问题上有过帮助; 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”(needle [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');

相反,我需要它们按照顶部使用数组(嵌套,并且针正在寻找匹配针[key]到haystack [array] [v1]

的匹配

虽然我已经摆弄并使用了早期的代码,我无法将其打成正确的形状:( 我继续通过foreach循环访问事物,并尝试使用for()等。

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

            // insert above methods

        }
    }
}

但我遇到了以下问题; 1)Array2(针头)很大,同一针出现多次? 2)我只获得一个匹配(即使数组1包含多个匹配数组2 Needle-n - 它只找到a)第一个或b)最后一个匹配 3)无论顺序/顺序如何都匹配(我认为我以某种方式破坏了代码,并且它将匹配“cccc bb aa”,当Needles中的顺序不存在时(它改为“aa bb cccc”)。

我现在花了两天的时间来解决这个问题。

我试图使用这两种解决方案(foreach和for方法)......但我无法让它们中的任何一种工作。

1 个答案:

答案 0 :(得分:1)

如果我理解你想要实现的目标,你可以这样做(见代码中的评论):

/* 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