13

I have a multi-dimensional array:

$categories = array(
    array(
        'CategoryID' => 14308,
        'CategoryLevel' => 1,
        'CategoryName' => 'Alcohol & Food',
        'CategoryParentID' => 14308
    ),
    // CHILD CATEGORIES
    array(
        array(
            'CategoryID' => 179836,
            'CategoryLevel' => 2,
            'CategoryName' => 'Alcohol & Alcohol Mixes',
            'CategoryParentID' => 14308
        ),
        array(
            array(
                'CategoryID' => 172528,
                'CategoryLevel' => 2,
                'CategoryName' => 'Antipasto, Savoury',
                'CategoryParentID' => 14308
            )
        )
    )
);

I need to get the exact location of the index, and since array_search doesn't work on multi-dimensional arrays, I'm using one of the functions provided on the PHP manual page.

function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
            return $current_key;
        }
    }
    return false;
}

.. but it also returns the key of the first array only:

echo recursive_array_search(172528, $categories); // outputs 1

I'm expecting:

[1][1][0]

4 Answers 4

19

You can change your recursive function like this, which should give you the solution:

function recursive_array_search($needle, $haystack, $currentKey = '') {
    foreach($haystack as $key=>$value) {
        if (is_array($value)) {
            $nextKey = recursive_array_search($needle,$value, $currentKey . '[' . $key . ']');
            if ($nextKey) {
                return $nextKey;
            }
        }
        else if($value==$needle) {
            return is_numeric($key) ? $currentKey . '[' .$key . ']' : $currentKey . '["' .$key . '"]';
        }
    }
    return false;
}

This will result in

[1][1][0]["CategoryID"]

Since CategoryID is also a key in your multidimensional array.

If you don't want this, you can adapt the function to

function recursive_array_search($needle, $haystack, $currentKey = '') {
    foreach($haystack as $key=>$value) {
        if (is_array($value)) {
            $nextKey = recursive_array_search($needle,$value, $currentKey . '[' . $key . ']');
            if ($nextKey) {
                return $nextKey;
            }
        }
        else if($value==$needle) {
            return is_numeric($key) ? $currentKey . '[' .$key . ']' : $currentKey;
        }
    }
    return false;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks heaps, that works. Sorry for the stupid question, but if I want to print the value of that fetched index, I can't print with $categories.$key, it just prints the categories and then the string literally.
I can't figure this out either, anyone?
3

You are ignoring the returned value of your inner call to recursive_array_search. Don't do that.

/*
 * Searches for $needle in the multidimensional array $haystack.
 *
 * @param mixed $needle The item to search for
 * @param array $haystack The array to search
 * @return array|bool The indices of $needle in $haystack across the
 *  various dimensions. FALSE if $needle was not found.
 */
function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        if($needle===$value) {
            return array($key);
        } else if (is_array($value) && $subkey = recursive_array_search($needle,$value)) {
            array_unshift($subkey, $key);
            return $subkey;
        }
    }
}

1 Comment

Hello. In array ["name" => "class_test", "static" => true, "public" => true, "interface" => false] the return is [0 => "static"], namely only returns the first element found. Returning all with this solution? [0 => "static", 1 => "public"]
0
public static function unique(array $data, $key){
    $rez = [];
    foreach($data as $val){
        if(!isset($val[$key]) && is_array($val)){
            return self::unique($val, $key);
        }elseif( isset($val[$key]) ){
            $rez[] = $val[$key];
        }
    }
    return array_unique($rez);
}

Comments

0
function array_search_recursive( $search, $values = array(), $i = 0) {
    $match = false;
    var_dump($i, $search);
    $i++;
    foreach ( $values as $keyState => $val ) {
        var_dump($val == $search, 'expression');
        if ( $val == $search ) {
            return $keyState;
        }
        if ( is_array( $val ) ) {
            $match = array_search_recursive($search, $val, $i);
        }
        if ( $match !== false ) {
            return $keyState;
        }
    }

    return false;
}
echo array_search_recursive($search, $canada)

Edit:

This will return the first key, tested for $canada = array( 'Brazilia' => 'test1', "Alberta" => [ "Airdrie", "Brooks", "Camrose" ], "British Columbia" => [ "Abbotsford" => [ 'a', 'b', 'c' ], "Armstrong", "Castlegar" ], "Manitoba" => [ "Brandon", "Selkirk" ], 'Olanda' => 'test2' ); $search = "Selkirk";

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.