barfurth
barfurth

Reputation: 661

PHP Find value in a multi-dimensional array by key

I receive a large multi-dimensional array from an API. I save the array into a class property and then I use a magic getter to disguise the array and have end users use keys as properties ($class->key ==> $class->data['key']).

Now the array I am dealing with is very much multi-dimensional and I need keys on different "levels" or layers. Imagine the array has two branches with multiple layers.

The keys I am looking for are usually the top level.

I will try to illustrate this:

Array
    baseKey
        key1
            value1
        key2
            value2
        key3
            subKey1
                value3
            subKey2
                value4
    key4
        value5
    key5
        subKey3
            value6
    key6
        subKey4
            subSubKey1
                value7

I am looking for a function that I can give any key to, including baseKey, key, subKey and subSubKey and that will return the respective value for the first key that matches.

So as an example:

awesomeFindByKey('key2') 
    ==> value2

awesomeFindByKey('subKey4') 
    ==> array('subSubKey1' => 'value7')

awesomeFindByKey('key6') 
    ==> array('subKey4' => array('subSubKey1' => 'value7'))

Is there a function for this or will I have to write one myself? Does anybody maybe have a function that does this?

I hope it was understandable. Thanks.

Upvotes: 0

Views: 177

Answers (1)

F. Müller
F. Müller

Reputation: 4062

Here is very simple sample implementation:

// sample class
class A {

  // the data array
  protected $data = array();

  // init
  public function __construct($data = null) {
    $this->setData($data);
  }

  // recursive search of a key
  private function searchLayer($key, $layer, $searchKey) {
    // return the layer if we have a match
    if ((string) $key === (string) $searchKey) return $layer;

    // loop the array if we need to go deeper
    if ((array) $layer === $layer) {
        foreach ($layer as $k => $v) {
            // apply recursition
            $result = $this->searchLayer($k, $v, $searchKey);

            // return on match
            if (!empty($result)) return $result;
        }
    }

    // nothing found - recursion ended here
    return null;
  }

  // returns the value of the data array with the given key
  public function getValueByKey($searchKey) {
    echo '<br>search by key: ' . $searchKey . '<br>';

    // check if we have a match
    foreach ($this->data as $key => $layer) {
        // resolve layer
        $result = $this->searchLayer($key, $layer, $searchKey);

        // return on match
        if (!empty($result)) return $result;
    }

    // nothing found
    return null;
  }

  // set the data
  public function setData($data) {
    if ((array) $data === $data) $this->data = $data;
  }

  // possible extension
  public function __get($key) {
    return $this->getValueByKey($key);
  }
}

// create the object of the class 'a'
$a = new A();

// set the data
$a->setData(array(
  'value1',
  'key2' => 'value2',
  'key3' => array(
    'subkey31' => 'value31',
    'subkey32' => 'value32'
  )
));

var_dump($a->getValueByKey('subkey32'));
var_dump($a->subkey32);

Output: string(7) "value32" string(7) "value32"

Test it here: http://writecodeonline.com/php just paste the code and hit run.

EDIT

Of course this is a very basic example - you could also use some of the given php-classes like others already said for example ArrayAccess.

Upvotes: 1

Related Questions