note 117618 deleted from function.array-search by peehaa
| From: | peehaa@php.net | Date: | Fri, 07 Apr 2017 10:34:10 +0000 |
| Subject: | note 117618 deleted from function.array-search by peehaa | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-208998@lists.php.net to get a copy of this message | ||
Note Submitter: raat1979 at gmail dot com
----
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; //empty haystack never contain a needle
if($offset>count($haystack)) return false; //looking higher then the top of the haystack will
never find anything
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); //becomes array(0=>1,1=>4);
$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){
//we correct the found fosition based on the position in the needle, as a result
//all matches set at the match position relative to start of needle
$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); //find all matches for which the
position count matches the needle count
}
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');
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 22 23 24 25
$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',
//26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 55 46
47 48 49 50 51
'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',
//52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
72 73 74 75 76
'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)