3

How do I detect if a certan sequence of elements is present in an array? E.g. if I have the arrays and needle

$needle = array(1,1);
$haystack1 = array(0,1,0,0,0,1,1,0,1,0);
$haystack2 = array(0,0,0,0,1,0,1,0,0,1);

How does one detect if the subset $needle is present in e.g. $haystack1? This method should return TRUE for $haystack1 and FALSE for $haystack2.

Thanks for any suggestions!

2
  • 1
    Are your arrays always just single-digit numeric values? Commented Jun 1, 2012 at 15:49
  • 1
    In my case, yes. Actually they'll always be boolean 1's and 0's as they represent target and non-target trials in a cognitive task. Commented Jun 3, 2012 at 14:07

3 Answers 3

6

Join the arrays, and check for the strpos of the needle.

if ( strpos( join($haystack1), join($needle) ) >= 0 ) {
    echo "Items found";
}

Demo: http://codepad.org/F13DLWOI

Warning

This will not work for complicated items like objects or arrays within the haystack array. This method is best used with itesm like numbers and strings.

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

1 Comment

Thank you, Jonathan! Very nice and simple solution.
3

If they're always a single digit/character then you can convert all elements to strings, join by '', and use the regex or string functions to search.

1 Comment

Thank you, Ignacio. I guess that's what Jonathan also proposed with code.
3

For the specific case where no array element is a prefix of any other element (when both are converted to strings) then the already posted answers will work fine and probably be pretty fast.

Here's an approach that will work correctly in the general case:

function subarray_exists(array $needle, array $haystack) {
    if (count($needle) > count($haystack)) {
        return false;
    }

    $needle = array_values($needle);
    $iterations = count($haystack) - count($needle) + 1;
    for ($i = 0; $i < $iterations; ++$i) {
        if (array_slice($haystack, $i, count($needle)) == $needle) {
            return true;
        }
    }

    return false;
}

See it in action.

Disclaimer: There are ways to write this function that I expect will make it execute much faster when you are searching huge haystacks, but for a first approach simple is good.

1 Comment

Thank you for putting this code here for the record, Jon. I was thinking of something like this too in the first place, but figured that there would be more clever solutions to my single-digits case.

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.