tags:

views:

52

answers:

5

Is there a better method than loop with strpos()?

Not i'm looking for partial matches and not an in_array() type method.

example needle and haystack and desired return:

$needles[0] = 'naan bread';
$needles[1] = 'cheesestrings';
$needles[2] = 'risotto';
$needles[3] = 'cake';

$haystack[0] = 'bread';
$haystack[1] = 'wine';
$haystack[2] = 'soup';
$haystack[3] = 'cheese';

//desired output - but what's the best method of getting this array?
$matches[0] = 'bread';
$matches[1] = 'cheese';

ie:

magic_function($haystack, %$needles%) !

A: 

array_intersect

hsz
Nope, won't compare `bread` against `naan bread`. The OP seems to be looking for a wildcard matching function.
Pekka
will this work for non-exact matches?
Haroldo
Dohh - missed that `naan`. Than he should explode all elements with space delimiter but that all is not then a native function at all.
hsz
+2  A: 
foreach($haystack as $pattern) {
    if (preg_grep('/'.$pattern.'/', $needles)) {
        $matches[] = $pattern;
    }
}
SilentGhost
Short and sweet.
Pekka
function magic_function($haystack, $needles) { // code above here :)}
hsz
returns an array with four elements: bread, cheese, bread, cheese
Gordon
+1  A: 

I think you'll have to roll your own. The User Contributed Comments to array_intersect() provide a number of alternative implementations (like this one). You would just have to replace the == matching against strstr().

Pekka
+1  A: 
$data[0] = 'naan bread';
$data[1] = 'cheesestrings';
$data[2] = 'risotto';
$data[3] = 'cake';

$search[0] = 'bread';
$search[1] = 'wine';
$search[2] = 'soup';
$search[3] = 'cheese';

preg_match_all(
    '~' . implode('|', $search) . '~',
    implode("\x00", $data),
    $matches
);

print_r($matches[0]); 

// [0] => bread
// [1] => cheese

You'll get better answers if you tell us more about the real problem.

stereofrog
+2  A: 

I think you are confusing $haystack and $needle in your question, because naan bread is not in haystack, nor is cheesestring. Your desired output suggests you are looking for cheese in cheesestring instead. For that, the following would work:

function in_array_multi($haystack, $needles)
{
    $matches = array();
    $haystack = implode('|', $haystack);
    foreach($needles as $needle) {
        if(strpos($haystack, $needle) !== FALSE) {
            $matches[] = $needle;
        }
    }
    return $matches;
}

For your given haystack and needles this performs twice as fast as a regex solution. Might change for different number of params though.

Gordon