Page 1 of 1

More efficient way to parse multi-dimensional array?

Posted: Mon Jun 13, 2011 1:41 am
by flying_circus
I'm sure there is a much more efficient way to do this, can you help?

Example:

Code: Select all

#Example Array
print_r($_SESSION);

Array
(
  [global] => Array
  (
    [user_id] => 1
  )

  [authentication] => Array
  (
    [last_impress] => 1307943328
    [token] => 1b20e459d77103ffc2c79c19300c12f2
  )
)
And the code to parse the multi-dimensional array:

Code: Select all

<?php
    function get_val()
    {
      $subject = $_SESSION;
      
      foreach(func_get_args() as $key) {
        if($subject)
          $subject = parse_key($key, $subject);
      }
      
      return $subject;
    }
    
    function parse_key($key, $subject)
    {
      if(array_key_exists($key, $subject))
        return $subject[$key];
      else
        return false;
    }
    
    print get_val('global', 'user_id'); // 1
    print get_val('authentication', 'token'); // 1b20e459d77103ffc2c79c19300c12f2
?>
In short, I want to pass n number of arguments to a function: get_val(n arguments...) and have it parse a multi-dimensional array to find the value.

If I knew it would be only 2 arguments, I could easily do $_SESSION[$arg1][$arg2], but since the number of arguments will be unknown, how do you parse an array like that?

Re: More efficient way to parse multi-dimensional array?

Posted: Mon Jun 13, 2011 10:54 am
by McInfo
Follow the keys down the hierarchy. The child becomes the parent.

Code: Select all

<?php
function lookup ($parent, $keys) {
    $numKeys = count($keys);
    $k = 0;
    while ($k < $numKeys && isset($parent[$keys[$k]])) {
        $parent = $parent[$keys[$k]];
        ++$k;
    }
    if ($k != $numKeys) {
        $parent = null;
    }
    return $parent;
}
$session = array (
    'global' => array (
        'user_id' => '1',
        'colors' => array (
            'white' => array (255, 255, 255)
        ),
    ),
    'authentication' => array (
        'last_impress' => '1307943328',
        'token' => '1b20e459d77103ffc2c79c19300c12f2',
    ),
);
var_dump(
    lookup($session, array('global', 'user_id')),
    # string(1) "1"
     lookup($session, array('user_id', 'global')),
    # NULL
     lookup($session, array('authentication', 'last_impress')),
    # string(10) "1307943328"
     lookup($session, array('authentication', 'token')),
    # string(32) "1b20e459d77103ffc2c79c19300c12f2"
     lookup($session, array('global', 'not_there')),
    # NULL
     lookup($session, array('global', 'colors')),
    # array(1) {
     #   ["white"]=>
     #   array(3) {
     #     [0]=>
     #     int(255)
     #     [1]=>
     #     int(255)
     #     [2]=>
     #     int(255)
     #   }
     # }
     lookup($session, array('global', 'colors', 'white')),
    # array(3) {
     #   [0]=>
     #   int(255)
     #   [1]=>
     #   int(255)
     #   [2]=>
     #   int(255)
     # }
     lookup($session, array('global', 'colors', 'white', 0))
    # int(255)
);
By the way, isset() is twice as fast as array_key_exists().

Re: More efficient way to parse multi-dimensional array?

Posted: Mon Jun 13, 2011 2:26 pm
by AbraCadaver
I also like passing in the keys as an array, and don't like the vague get_info(), but you could also foreach the func_get_args() *not tested:

Code: Select all

function get_session_value($keys) {
    $subject = $_SESSION;
    
    foreach($keys as $key) {
        if(isset($subject[$key])) {
            $subject = $subject[$key];
        } else {
            return false;
        }
    }
    return $subject;
}

Re: More efficient way to parse multi-dimensional array?

Posted: Tue Jun 14, 2011 3:33 pm
by flying_circus
Thank you to both of you. I appreciate the feedback and the new perspective :)