1

I have been working on this problem, but i have had no result with current functions of PHP.

I have a multidimensional array, like:

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

    [4] => Array
        (
            [22] => 3
            [23] => 4
        )

    [5] => Array
        (
            [1] => 5
        )

)

If the first keys of array were static, it would have been easy to fix, but all the keys are dynamical data. (3, 4, 5 etc...). I like to have a function that finds the keys of a value.

myFunction($myArray, 3) // 3 = my value.

If there is a value "3", I want function to give me the keys of it. (4, 22). Just like the array on the top.

Thanks in advance.

6
  • I do not get why, by passing to your function 3 in parameter, it would gives Array [4, 23]. If there is a value "3", what you call value ? Because in your array, the only value I see is [22] => 3, so its key is 22, and the key of its key is 4. So it would output [4, 22] and not like you said [4, 23]. Or am I wrong ? Commented Nov 8, 2016 at 13:49
  • Moreover, I suppose that if you're searching for 3, it has to return (4,22). Commented Nov 8, 2016 at 13:52
  • Yes, @Giuserv.. Commented Nov 8, 2016 at 13:57
  • @ArdaTahsinAyar So my answer above does what you want Commented Nov 8, 2016 at 13:58
  • Tested it and looks like does, thank you for your fast-help. @GiuServ Commented Nov 8, 2016 at 14:02

8 Answers 8

1

Suppose you want an array of keys with the index of the array which contains the searched value (3), and the index of the 3 value in that array, this should works:

$matched = [];
foreach($object as $extIndex => $array){
    foreach($array as $intIndex => $value){
        if($value == 3){
            $matched[] = [$extIndex, $intIndex];
        }
    }
}
var_dump($matched);

edit: $object is the object as described in the question.

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

Comments

1

Here is the solution if you are sure that your input array will always be only 2D.

$test = [
  3 => [
    16 => 0,
    17 => 1,
    18 => 2],
  4 => [
    22 => 3,
    23 => 4],
  5 => [
    1 => 5]
];

function myFunction($array, $value){
    foreach($array as $k => $a){
        if(in_array($value, $a)){
            return ([$k,array_keys($a,$value)]);
        }
    }
}
var_dump(myFunction($test, 3));

This will output:

array(2) { [0]=> int(4) [1]=> array(1) { [0]=> int(22) } }

Please mind that second value in returned array is itself an arrray because there can exist more than one 3 in array.

I hope it helps

Comments

1

After seeing what you specifically want:

$array_data = [
  3 => [
    16 => 0,
    17 => 3,
    18 => 2],
  4 => [
    22 => 3,
    23 => 4],
  5 => [
    1 => 5]
];

function findKeysFromValue($search, $array){

    foreach($array as $key => $value){
        $b = [];
        foreach($value as $k => $v){
            if($v != $search){
                unset($array[$key][$k]);
            } else {
                $b[] = $k;
            }
        }
        $array[$key] = $b;
    }

    return array_filter($array,'count');
}

print_r(findKeysFromValue(3, $array_data));

The output would be the following:

Array(
  [3] => Array(
      [0] => 17
    )
  [4] => Array(
      [0] => 22
    )
)

1 Comment

Thanks, but it gives all the keys in array, I just want of the value i want.
0

Maybe this will work (I haven't tried it though).

function findInArray($array, $search, $parentPath) {
      foreach ($array as $key => $value) {                
            $currentPath = array_merge($parentPath, $key);
            if (!is_array($value) && $value === $search) {
                return $currentPath;
            } else if (is_array($value)) {
                $res = findInArray($value, $search, $currentPath);
                if ($res !== null) {
                    return $res;
                }
            }
      }
      return null;
}

Call as findInArray($array, 3, [])

Comments

0

This function works with 2 dimens array:

function findKey( $arr, $arrValue ) {
    foreach ( $arr as $key => $value ) {
        foreach ( $value as $subKey => $subValue ) {
            if ( $arrValue == $subValue ) {
                return $subKey;
            }
        }
    }

    return - 1;
}

$mdArray = array(
    12 => array(
        3 => 4,
        4 => 8,
        7 => 9
    ),
    23 => array(
        5  => 5,
        8  => 12,
        11 => 18
    ),
);

echo findKey( $mdArray, 4 ); //3
echo findKey( $mdArray, 5 ); //5
echo findKey( $mdArray, 8 ); //4
echo findKey( $mdArray, 12 ); //8

Comments

0

How about a function that searches for your first key then returns the keys belonging to the first array as an array so you can traverse the values like this:

<?php

    function FindTheKeys($myArray, $myKey)
    {
            foreach ($myArray as $firstkeys => $firstvalues)
            {
                    if ($firstkeys == $myKey)
                    {
                            return array_keys($firstvalues);
                    }
            }
    }

    $myarr = Array
    (
            3 => Array
            (
                    16 => 0,
                    17 => 1,
                    18 => 2
            ),

            4 => Array
            (
                    22 => 3,
                    23 => 4
            ),

            5 => Array
            (
                    1 => 5
            )

    );

    $foundkeys = FindTheKeys($myarr, 3);

    print_r($foundkeys);

?>

The above will return 16, 17, 18 in an array $foundkeys.

Comments

0

How about a recursive function that searches to any depth of array and returns the first value match.

Demonstration : https://eval.in/674271

How: Search the array looking for the value.

  • Each time we meet a new array we need to search it.
  • so, record the current key in a stack ad then recurse to search it.
  • If we find the value then end.
  • Otherwise, we throw away the top of the stack and keep looking.

The function that does the work:

/**
 *  This will recurse until it finds the value.
 *  stop on first match 
 *
 *  @param array $haystack - where to look 
 *  @param mixed $needle   - what to look for
 *  @param array $keyPath  - reference to result array that will store the path   
 *
 *  @return  boolean $found
 */
function findKeys(array $haystack, $needle, &$keyPath)
{
     $found = false;

     foreach ($haystack as $key => $value) {

        if (is_array($value)) { // record current key and recurse 
            array_push($keyPath, $key);
            $found = findKeys($value, $needle, $keyPath);   
            if ($found) {
                return $found;
            }             
            array_pop($keyPath);


        } else {
            $found = $value === $needle;
            if ($found) {
                array_push($keyPath, $key);
                break;
            }
        } 
     }

     return $found;   
}

Run it:

$path = array();

$found = findKeys($src, 42, $path);

Sample output:

string(6) "Found:"
bool(true)

Path
Array
(
    [0] => 4
    [1] => 24
    [2] => 126
)

Comments

-1

You can avoid one looping by using this.

$matched = [];
foreach($object as $extIndex => $array){
    //Look for value 3 in the array until no value is found
    while (false !== $key = array_search(3, $array)) {
        $matched[] = [$extIndex, $key];
        //Remove the value already found
        unset($array[$key]);
    }

}
print_r($matched);

2 Comments

It works with only 1 value for array, if 3 is present more than one time for array, it would return only first match
Now it can work, but now you do a new loop, and also making an extra operation to unset the value from the array (and i also think that in this way you're also editing the original object)

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.