1

Array A:

486 987

Array B:

247-16-02-2009 486-16-02-2009 562-16-02-2009 1257-16-02-2009 486-16-02-2009 

I want to search and list all Array A elements that matches in Array B. for example: 486-16-02-2009 (twice).

4 Answers4

3

You can use a regex by imploding $arrayA into a pattern. This will find $arrayA items anywhere in $arrayB items:

$pattern = implode("|", $arrayA);
$result  = preg_grep("/$pattern/", $arrayB);

To match only at the start of $arrayB items use the ^ anchor "/^$pattern/".

You may want to run $arrayA elements through preg_quote() if there may be special pattern characters there.

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • 1
    Interesting approach! – Lando Feb 17 '16 at 18:42
  • Definitely an interesting and unique approach, so +1 for that. Overall, I like this approach; however, how would this compare to looping in terms of processing time and overhead? The RegEx engine requires a decent amount of overhead (memory) and generally has a slower processing time for such simple tasks like this. In the OP's example, the processing time and overhead would be miniscule/negligible, but the use of RegEx may have adverse effects on scalability. Nonetheless, this answer deserves an upvote because it is so short and unique from all other answers. – Spencer D Feb 17 '16 at 18:54
  • It returns empty array: /*$pattern = preg_quote(implode("|", $arrayA), "/"); $result = preg_grep("/^$pattern/", $arrayB); while pipe sign "|" returns all elements of $arrayB. but it doesn't return the match! – Shehryar Khalid Mar 04 '16 at 10:44
  • Edited. preg_quote was escaping the | – AbraCadaver Mar 04 '16 at 13:09
  • Thank you, it worked. I have a basic question in mind, how preg_grep function match "/$pattern/" in the source string "n40000|315758|465213|"? what would be the pattern? if I implode Array A string with asterisk "*". Thank you for your kind help Sir. – Shehryar Khalid Mar 05 '16 at 11:29
  • In the pattern the `|` means OR so `486 OR 987`. The `|` in the source string makes no difference. – AbraCadaver Mar 06 '16 at 03:21
2

You could do something like this, however it's probably not as good as using php built-ins like array-intersect because we're entering loop-hell. If either array gets too big your script will slow to a crawl.

foreach ($arrB as $values) {
    foreach ($arrA as $compare) {
        if (substr($values, 0, strlen($compare)) == $compare) {
            //do stuff
        }
    }
}
Lando
  • 419
  • 3
  • 8
1

You must walk the two arrays searching for each case:

Working example: http://ideone.com/pDCZ1R

<?php


$needle = [486, 987];
$haystack = ["247-16-02-2009", "486-16-02-2009", "562-16-02-2009", "1257-16-02-2009", "486-16-02-2009"];

$result = array_filter($haystack, function($item) use ($needle){
    foreach($needle as $v){
        if(strpos($item, strval($v)) !== false){
            return true;
        }
    }
    return false;
});

print_r($result);
Carlos Gant
  • 731
  • 6
  • 15
0

Somewhat similar to two of the other answers, but this would be my approach:

$matches = array(); // We'll store the matches in this array

// Loop through all values we are searching for
foreach($arrayA as $needle){
    // Loop through all values we are looking within
    foreach($arrayB as $haystack){
        if(strpos($needle, $haystack) !== false){
            // We found a match.
            // Let's make sure we do not add the match to the array twice (de-duplication):
            if(!in_array($haystack, $needle, true)){
                // This match does not already exist in our array of matches
                // Push it into the matches array
                array_push($matches, $haystack);
            }
        }
    }
}

Note: This solution uses in_array() to prevent match duplication. If you would like matches that match more than one value to show up more than once, then simply remove the if-statement that has !in_array(...) as its conditional.

Spencer D
  • 3,376
  • 2
  • 27
  • 43