I needed to search for sequences of values in an array,
In addition I needed to search from a given offset.
Unfortunately for neither I could find a function to do this.
This Is how I did it,
The function returns the position where position 0 of the needle matches
<?php
function array_find($needle,array $haystack,$offset=0,$length=null,$strict = false,$returnAll = false,$resultsBeforeStart=false){
if(count($haystack)===0) return false; if($offset>count($haystack)) return false; if($offset!==0) $haystack = array_slice($haystack, $offset, $length , true);
if(is_array($needle) && count($needle)===1) $needle = array_pop($needle);
if(!is_array($needle)){
$matches = array_keys($haystack,$needle,$strict);
}else{
$needleKeys = array_keys($needle); $needlePositions = array();
foreach($needleKeys as $key=>$pos){
$needlePartPositions = array_keys($haystack,$needle[$pos],$strict);
if(count($needlePartPositions)===0) return false;
foreach($needlePartPositions as $fkey=>$fval){
$matchStart = $fval-$pos;
if($matchStart >= 0 && ($matchStart>=$offset || $resultsBeforeStart)){
if(!isset($needlePositions[$matchStart])){
$needlePositions[$matchStart] = 1;
}else{
$needlePositions[$matchStart]++;
}
}
}
}
$matches = array_keys($needlePositions,count($needle),true); }
if($matches === false) return false;
if(count($matches)===0) return false;
if($returnAll) return $matches;
return array_shift($matches);
}
$needle1 = array(1=>'D',4=>'G');
$needle2 = array('D','E');
$needle3 = array(1=>'D',2=>'E');
$haystack = array('A','B','C','D','E','F','G','H','I','J','H','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'A','B','C','D','E','F','G','H','I','J','H','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'A','B','C','D','E', 'G','H','I','J','H','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
var_dump(array_find($needle1,$haystack,0,null,true,true));
var_dump(array_find($needle1,$haystack,29,null,true,true));
var_dump(array_find($needle1,$haystack,29,null,true,true,true));
var_dump(array_find($needle2,$haystack,0,null,true,true));
var_dump(array_find($needle2,$haystack,55,null,true,false));
var_dump(array_find($needle2,$haystack,56,null,true,false,true));
?>
// D is at position 3 and 29 but they are matched at position 1 of the needle
// position 0 of the needle would therefore be at 2 and 28
array(2) {
[0]=> int(2)
[1]=> int(28)
}
//no match after position 29 that is after the start position
bool(false)
// items in the needle are matched at position 29 but needle starts at 1, $resultsBeforeStart was true so this one is included
array(1) {
[0]=> int(28)
}
// D,E found at 3 positions
array(3) {
[0]=> int(3)
[1]=> int(29)
[2]=> int(55)
}
//search for D,E starting at position 55 finds 1 match
int(55)
//search for D,E starting at position 56 finds NO matches, even if $resultsBeforeStart is set to true because the needle starts at position 0
bool(false)