3

So what I need is to compare a string to an array (string as a haystack and array as a needle) and get the elements from the string that repeat within the array. For this purpose I've taken a sample function for using an array as a needle in the substr_count function.

$animals = array('cat','dog','bird');
$toString = implode(' ', $animals);
$data = array('a');

function substr_count_array($haystack, $needle){
     $initial = 0;
     foreach ($needle as $substring) {
          $initial += substr_count($haystack, $substring);
     }
     return $initial;
}

echo substr_count_array($toString, $data);

The problem is that if I search for a character such as 'a', it gets through the check and validates as a legit value because 'a' is contained within the first element. So the above outputs 1. I figured this was due to the foreach() but how do I bypass that? I want to search for a whole string match, not partial.

1
  • I need to match the whole word as an element. Commented Jul 18, 2014 at 3:37

2 Answers 2

2

You can break up the $haystack into individual words, then do an in_array() check over it to make sure the word exists in that array as a whole word before doing your substr_count():

$animals = array('cat','dog','bird', 'cat', 'dog', 'bird', 'bird', 'hello');
$toString = implode(' ', $animals);
$data = array('cat');

function substr_count_array($haystack, $needle){
    $initial = 0;
    $bits_of_haystack = explode(' ', $haystack);
    foreach ($needle as $substring) {
        if(!in_array($substring, $bits_of_haystack))
            continue; // skip this needle if it doesn't exist as a whole word

        $initial += substr_count($haystack, $substring);
    }
    return $initial;
}

echo substr_count_array($toString, $data);

Here, cat is 2, dog is 2, bird is 3, hello is 1 and lion is 0.


Edit: here's another alternative using array_keys() with the search parameter set to the $needle:

function substr_count_array($haystack, $needle){
    $bits_of_haystack = explode(' ', $haystack);
    return count(array_keys($bits_of_haystack, $needle[0]));
}

Of course, this approach requires a string as the needle. I'm not 100% sure why you need to use an array as the needle, but perhaps you could do a loop outside the function and call it for each needle if you need to - just another option anyway!

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that solves it. Thanks for the time allocated. Will accept the answer as soon as possible.
0

Just throwing my solution in the ring here; the basic idea, as outlined by scrowler as well, is to break up the search subject into separate words so that you can compare whole words.

function substr_count_array($haystack, $needle) 
{
    $substrings = explode(' ', $haystack);

    return array_reduce($substrings, function($total, $current) use ($needle) {
        return $total + count(array_keys($needle, $current, true));
    }, 0);
}

The array_reduce() step is basically this:

$total = 0;
foreach ($substrings as $substring) {
    $total = $total + count(array_keys($needle, $substring, true));
}
return $total;

The array_keys() expression returns the keys of $needle for which the value equals $substring. The size of that array is the number of occurrences.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.