How to code up a [find-array-in-array]
function?
Psuedo-code
Haystack:
array(0=a, 1=b, 2=a, 3=b, 4=c,
My attempt at creating this function;
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');
print_r(find_array_in_array($needle, $haystack));
Outputs;
Array
(
[0] => Array
(
[0] => 2
[1] => 3
[2] => 4
)
[1] => Array
(
[0] => 12
[1] => 13
[2] => 14
)
)
If the haystack consists of letters, you can do this in the string domain:
$haystack = array('a', 'b', 'a', 'b', 'c', 'c', 'a', 'b', 'd', 'c', 'a', 'b', 'a', 'b', 'c');
$haystack = join('', $haystack);
preg_match_all('/abc/', $haystack, $matches, PREG_OFFSET_CAPTURE);
print_r(array_map(function($item) {
return range($item[1], $item[1] + strlen($item[0]) - 1);
}, $matches[0]));
Output:
Array
(
[0] => Array
(
[0] => 2
[1] => 3
[2] => 4
)
[1] => Array
(
[0] => 12
[1] => 13
[2] => 14
)
)
With potentially multiple characters inside the haystack, you need to resort to this:
$haystack = array('a', 'b', 'a', 'b', 'c', 'c', 'a', 'b', 'd', 'c', 'a', 'b', 'a', 'b', 'c');
$needle = array('a', 'b', 'c');
// 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);