我从API接收一个大型多维数组。我将数组保存到类属性中然后使用魔术getter来伪装数组并让最终用户使用键作为属性($class->key ==> $class->data['key']
)。
现在我正在处理的数组非常多维,我需要键在不同的"级别"或层。想象一下,该数组有两个分支,有多个层。
我正在寻找的钥匙通常是顶级的。
我将尝试说明这一点:
Array
baseKey
key1
value1
key2
value2
key3
subKey1
value3
subKey2
value4
key4
value5
key5
subKey3
value6
key6
subKey4
subSubKey1
value7
我正在寻找一个可以提供任何密钥的功能,包括baseKey
,key
,subKey
和subSubKey
,这将返回相应的值第一个匹配的密钥。
以此为例:
awesomeFindByKey('key2')
==> value2
awesomeFindByKey('subKey4')
==> array('subSubKey1' => 'value7')
awesomeFindByKey('key6')
==> array('subKey4' => array('subSubKey1' => 'value7'))
是否有这个功能,还是我必须自己写一个?有没有人可能有这样做的功能?
我希望这是可以理解的。感谢。
答案 0 :(得分:1)
以下是非常简单的示例实现:
// 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);
输出:string(7) "value32" string(7) "value32"
在此处测试:http://writecodeonline.com/php只需粘贴代码并点击运行。
修改强>
当然这是一个非常基本的例子 - 您也可以使用一些给定的php类,就像其他人已经说过的那样ArrayAccess
。
答案 1 :(得分:-1)
如果数组存储在类中,则可以实现PHP提供的ArrayAccess
接口。这将使您能够在不同的语言结构中使用(内部)数组,并且能够将类本身用作数组。
示例:
$value = $class['base_key']['key']['sub_key'];
这也有一个优点,你可以拥有任意数量的级别。我认为这比你提出的只能处理3级深度数组的函数更方便。
<强>更新强>
建议功能的可能实现如下所示:
public function resolve_key($key, $array) {
/*
* Check if the key exists in the first array level.
*/
if(array_key_exists($key, $array)) {
return $array[$key];
}
/*
* Check if the key exists as a sub key in the value of each array element.
*/
foreach($array as $value) {
if(is_array($value)) {
return resolve_key($key, $value);
}
}
/*
* Return NULL if no key was found or throw an exception.
*/
return null;
}
这使用递归(在评论中由Karoly Hovarth提出)。首先检查所提供的数组的第一级是否存在所请求的密钥。如果没有,那么对于作为数组的每个数组值,再次执行该函数。
为了能够将密钥作为类属性找到,请使用以下命令:
public function __get($key) {
return $this->resolve_key($key, $this->internal_array);
}
希望这有帮助。