0

I have 2 arrays, I need to find if one of the values in array one matches one of the values in array two, a multi-dimensional array. I also need to check that the value from array one is in a specific key in array two, the "principal" key as the "authority" key may also hold this value.

here is array one:

Array
(
    [0] => 17
    [1] => 6
    [2] => 3
    [3] => 2
)

and array two [actually slightly truncated for readability]:

Array
(
    [modAccessResourceGroup] => Array
        (
            [3] => Array
                (
                    [0] => Array
                        (
                            [principal] => 0
                            [authority] => 9999
                            [policy] => Array
                                (
                                    [load] => 1
                                )

                        )

                    [1] => Array
                        (
                            [principal] => 2
                            [authority] => 10
                            [policy] => Array
                                (
                                    [add_children] => 1
                                    [create] => 1
                                    [copy] => 1
                                    [delete] => 1
                                    [list] => 1
                                    [load] => 1
                                    [move] => 1
                                    [publish] => 1
                                    [remove] => 1
                                    [save] => 1
                                    [steal_lock] => 1
                                    [undelete] => 1
                                    [unpublish] => 1
                                    [view] => 1
                                )

                        )

                    .... truncated ....

                    [13] => Array
                        (
                            [principal] => 16
                            [authority] => 9999
                            [policy] => Array
                                (
                                    [load] => 1
                                )

                        )

                )

            [8] => Array
                (
                    [0] => Array
                        (
                            [principal] => 0
                            [authority] => 9999
                            [policy] => Array
                                (
                                    [load] => 1
                                )

                        )

                    [1] => Array
                        (
                            [principal] => 1
                            [authority] => 9999
                            [policy] => Array
                                (
                                    [add_children] => 1
                                    [create] => 1
                                    [copy] => 1
                                    [delete] => 1
                                    [list] => 1
                                    [load] => 1
                                    [move] => 1
                                    [publish] => 1
                                    [remove] => 1
                                    [save] => 1
                                    [steal_lock] => 1
                                    [undelete] => 1
                                    [unpublish] => 1
                                    [view] => 1
                                )

                        )

                    [2] => Array
                        (
                            [principal] => 22
                            [authority] => 9999
                            [policy] => Array
                                (
                                    [add_children] => 1
                                    [create] => 1
                                    [copy] => 1
                                    [delete] => 1
                                    [list] => 1
                                    [load] => 1
                                    [move] => 1
                                    [publish] => 1
                                    [remove] => 1
                                    [save] => 1
                                    [steal_lock] => 1
                                    [undelete] => 1
                                    [unpublish] => 1
                                    [view] => 1
                                )

                        )

                )

        )

) 

I was using a series of foreach(){foreach(){foreach(){}}} but it seemed very messy and inefficient. Having some trouble getting my head around this. Any ideas?

Sean Kimball
  • 4,506
  • 9
  • 42
  • 73

2 Answers2

1

A recursive function should do the trick:

$values = array(17, 6, 3, 2, 5);

function find($array, &$values) {
    foreach ($array as $key => $element) {
        if (is_array($element)) {
            find($element, $values);
        }

        elseif ($key == 'principal') {
            foreach ($values as $value) {
                if ($element == $value) {
                    echo 'Found' . PHP_EOL;
                    // Do stuff
                }
            }
        }
    }
}

find($array, $values);
Michael Thessel
  • 706
  • 5
  • 20
  • I will certainly try, but I need to keep it as light as possible ~ the code could conceivably be executed up to 2000 times per request. i.e. searching recursively through 2000+ array per request. – Sean Kimball Apr 09 '13 at 00:41
  • Recursion is usually pretty fast, but if you can, you might want to try saving the principal values in a separate single-dimensional array so you can use the in_array function to check if a value is in there. If that's all you need, this would be really fast. – Revent Apr 09 '13 at 00:47
  • As Revent suggested [array_walk_recursive](http://php.net/manual/en/function.array-walk-recursive.php) is a good solution too. – Michael Thessel Apr 09 '13 at 17:03
1

Several things come to mind. First, in situations like this, I will usually create a separate array with just the principal values so that I can loop over the first array and just use a simple in_array() check. Secondly, if you don't want to do that, you could do something using the array_walk_recursive() function or some of the recursive examples in array_search() to go through your second array.

Revent
  • 2,091
  • 2
  • 18
  • 33
  • I've been trying to use, in_array($memberof, $value, true) where $memberof is array one and the $value are the deepest nested arrays, but for some reason it does not work? Does in_array only work on strings if you try to pass an array as the needle? – Sean Kimball Apr 09 '13 at 00:40
  • Ya, I have only used it for single-dimensional arrays - I don't think it's built to do complex searches. That's why a recursive array search is needed here. – Revent Apr 09 '13 at 00:43
  • In regards to: in_array($memberof, $value, true) where $memberof is array one and the $value are the deepest nested arrays - it *should* work using $memberof as the needle (assuming PHP 4.2 or later), but you might try setting the third value to false so that it won't do the strict type matching and will match 1 with '1'. I'd have to see your code to know if there was some other reason why it doesn't work. – Revent Apr 09 '13 at 01:31