3

Edit: I meant to ask what is the best/fastest way to get the first match or the first xx matches.

I have an array

$arr = ('abc', 'ded', 'kjld', 'abr', 'cdfd');

I want to shuffle this array first, and then retrieve ONLY the first value that matches the pattern /ab/. So, the returned value could be abc or abr.

I looked at preg_grep, but it will return an array of all the matches. Of course I could just retrieve the first value of the resultant array, but that is wasteful and requires an extra step of array manipulation. Is there another function or a preg_grep switch that specifies return only the first matched value (or first 5 matched values). I have looked at preg_match and preg_search, but they don't seem to give what I want.

Junuxx
  • 14,011
  • 5
  • 41
  • 71
Jamex
  • 1,164
  • 5
  • 22
  • 34

2 Answers2

6

You can loop through your array and end the loop when you find a match using break:

foreach($arr as $value) {
    if(preg_match($pattern,$value)) {
        $return_string=$value;
        break;
    }
}

To specify a limit:

$limit=3;
$i=0 // sets the number of returned results to 0
$results=array();
foreach($arr as $value) {
    if(preg_match($pattern,$value)) {
        // add the result into the array and increment the counter
        array_push($results,$value);
        $i++;
    } if ($i=$limit) break;
}

You can then use another foreach loop to return your values like:

if(count($results)>0)
foreach ($results as $result) {
    echo $result;
} else echo "No results found";
Ben Ashton
  • 1,385
  • 10
  • 15
  • Thanks Ben, it works great to get the first match. Now I need to research how to get the first 3 matches. – Jamex Mar 06 '12 at 19:04
  • You can also add a limit in the foreach by specifying a limit to a number you increment upon match, instead of breaking out of the loop. I will update my answer shortly to accommodate that – Ben Ashton Mar 06 '12 at 19:09
  • Thanks Ben for the help, I also did something similar to your limit approach, and tested the speed against the method of using preg_grep & array_slice to obtain only a array of certain size. My original array to search has about 9000 values, so preg_match is faster if I only want the first value and the first value does not occur at the end of the array. But preg_grep and slice is faster if more than 5 matches is needed. The orig intend was to find out whether there is a build-in array_slice option for the preg_grep method. Also in your code, use $result[]=$value is faster than array_push. – Jamex Mar 06 '12 at 20:30
3

Well I believe running preg_grep and then getting the first value would be fine, but alternatively you could loop your array and return when a match is found like this:

function firstMatch($arr,$pattern) {
    foreach($arr as $item) {
        if(preg_match($pattern,$item)) {
            return $item;
        }
    }
    return 'no match';
}
Brian Glaz
  • 15,468
  • 4
  • 37
  • 55
  • You're missing `shuffle`, but way to go :) – Vyktor Mar 06 '12 at 18:02
  • shuffle is not missing, that function work with or without a shuffled array. – hakre Mar 06 '12 at 18:14
  • What in case of `firstMatch(array('abc','def','no match'), '/match/')`? – Tadeck Mar 06 '12 at 18:39
  • @Tadeck obviously you could just change `return 'no match'` to `return false` if you wanted to. Depends on implementation really. – Brian Glaz Mar 06 '12 at 18:43
  • @BrianGlaz: I know that, but SO is full of people who would rather copy your code without modification. This is why I asked this question - for them to think a second before doing it exactly like they can see it within your answer. – Tadeck Mar 06 '12 at 18:45