I need to look through Array1, finding any matching sequences from Array2, and update corresponding sub-arrays in Array1.
I previously had help on a similar question;
Find array in array, in sequence
The previous solutions worked fantastically - but this time I'm dealing with more complicated data, and I need to update the Haystack array (rather than simply return the matches).
Array 1 : Haystack
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] => )
)
Array 2 : Needles
Array (
[0] => Array ( [aa] => nnnn [bb] => nnn [cccc] =>n )
[1] => Array ( [aa] => ddd [bb] => dd )
)
Thus I should find "aa bb cccc" (needle[0]) in the haystack, and update the array to become;
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] => )
)
The 2 versions of code I have are;
Code version 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);
and
Code version 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;
}
But these are designed to work with flat arrays;
$haystack = array('a', 'b', 'a', 'b', 'c', 'c', 'a', 'b', 'd', 'c', 'a', 'b', 'a', 'b', 'c');
$needle = array('a', 'b', 'c');
Instead, I need them to work with the arrays as per the top (nested, and the needles are looking for matches to the needle[key] to the haystack[array][v1]
Though I've fiddled and faffed with the earlier code, I cannot beat it into the right shape :(
I keep going through foreach loops to access things, and tried using for() etc.
foreach ($needlebox as $needles){
foreach ($needles as $needlekey=>$needlevalue){
foreach ($haystack as $haystackkey=>$haystackvalues){
// insert above methods
}
}
}
but I hit the following issues;
1) Array2 (Needles) is huge, with the same needles appearing multiple times?
2) I only get a single match (even if Array 1 contains multiple matches to Array 2 Needle-n - it only finds a) the first or b) the last)
3) It matches regardless of order/sequence (I think I broke the code somehow, and it will match "cccc bb aa", when that order in Needles does not exist (it's instead "aa bb cccc").
I've now spent 2 days faffing with this wondering what I've done wrong.
I've attempted to use both solutions (the foreach and the for methods) ... but I cannot get either of them to work.