0

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

我以前在类似问题上得到过帮助; 在数组中按顺序查找数组

以前的解决方案效果非常好——但这次我要处理更复杂的数据,我需要更新 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');

相反,我需要他们按照顶部处理数组(嵌套,并且针正在寻找与 needle[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 (Needles) 很大,相同的针头多次出现?2)我只得到一个匹配项(即使 Array 1 包含与 Array 2 Needle-n 的多个匹配项 - 它只找到 a)第一个或 b)最后一个)3)无论顺序/顺序如何,它都匹配(我想我打破了代码不知何故,它会匹配“cccc bb aa”,当针中的订单不存在时(而是“aa bb cccc”)。

我现在花了 2 天的时间来处理这个问题,想知道我做错了什么。

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

4

1 回答 1

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

另请参阅这个简短的演示

于 2013-06-20T20:09:31.307 回答