我需要查看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方法)......但我无法让它们中的任何一种工作。
答案 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 。