Reputation: 661
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
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