Alexandru R
Alexandru R

Reputation: 8833

Access deep array value in php using an array of keys/indices in php?

Suppose you have this array:

$object = array ('a' => array ( 'b' => array('c' = 'value'), 'd' => 3));
$indices = array ('a', 'b', 'c');

Is there an easy way to access $object['a']['b']['c'] (keys from $indices array)?

This is what I tried:

function accessObjectKey ($object, $levels) {
    if (is_string($levels)) 
        $levels = explode ('.', $levels);
    //
    for ($i=0; $i<count($levels); $i++) {
        if ($i == count($levels) && key_exists($levels[$i], $object)) {
            $value = $object[$levels[$i]];
        }
        else {
            $value = accessObjectKey ($object, array_shift($levels));
        }
    }
    return $value;
}

Thank you

Upvotes: 2

Views: 1638

Answers (3)

mickmackusa
mickmackusa

Reputation: 47903

Another technique is to use explicit stacking.

I came upon this page while searching for related techniques for this CodeReview question.

By "stacking", I actually mean iterate the array of keys which dictate the path to the desired array value and each time a key is found, overwrite the parent array with the newly encountered subarray.

Code: (Demo)

function getFromKeyPath(array $array, array $keys) {
    foreach ($keys as $index => $key) {
        if (!key_exists($key, $array)) {
            throw new Exception("key $key not found at level index $index");
        }
        $array = $array[$key];
    }
    return $array;
}

$array = ['a' => ['b' => ['c' => 'value'], 'd' => 3]];
$keys = ['a', 'b', 'c'];

try {
    var_export(getFromKeyPath($array, $keys));
} catch (Exception $e) {
    echo $e->getMessage();
}
// 'value'

Upvotes: 0

Rafael Vega
Rafael Vega

Reputation: 4645

Here's another option, from https://baohx2000.medium.com/reaching-deep-into-arrays-using-array-reduce-in-php-9ff9e39a9ca8

function getArrayPath(array $path, array $deepArray) {
   $reduce = function(array $xs, $x) {
      return (
        array_key_exists($x, $xs)
      ) ? $xs[$x] : null;
   };
   return array_reduce($path, $reduce, $deepArray);
}

$x = [
  'a' => 1,
  'b' => [
    'c' => 2,
    'd' => [3, 4, 5],
  ],
];

print_r(getArrayPath(['b','d', 0], $x));  // 3

Upvotes: 1

Alex
Alex

Reputation: 17289

First of all (you have typo array('c' = 'value'), should be array('c' => 'value'),) I tried to use your code:

$object = array ('a' => array ( 'b' => array('c' => 'value'), 'd' => 3));
$indices = array ('a', 'b', 'c');

echo accessObjectKey($object,$indices);

that returned me an error:

Fatal error: Maximum function nesting level of '100' reached, aborting!

I was little bit confusing by your function code, so sorry I created mine It is not perfect but return value as expected:

function getByPath($arr,$path) {
     if (!isset($arr[$path[0]])) {
        return 'There is no '.$path[0].' element!';
     } elseif(count($path)==1) {
        return $arr[$path[0]];
     } elseif(!is_array($arr[$path[0]])) {
        return 'Element '.$path[0].' is not array! ';
     } else {
    $key = array_shift($path);     
        return getByPath($arr[$key],$path);
     }
}

$object = array ('a' => array ( 'b' => array('c' => 'value'), 'd' => 3));
$indices = array ('a', 'b', 'c');

echo getByPath($object,$indices);

output:

value

Upvotes: 2

Related Questions