我试图访问一个嵌套数组(一个包含数组的数组,其中包含数组......)
给定数组和键的路径,我需要得到最后一个值。
鉴于foo和......我需要得到
foo[a][b][c]…[x][y][z]
我想知道是否还有比这更优雅的方式?
function getValueRecursive(array $array, string ...$identifyer){
$value = $array;
foreach($identifyer as $key){
if(!key_exists($key, $value))
return NULL;
$value = $value[$key];
}
return $value;
}
$foo = [
'a' => [
'b' => [
'c' => "Hallo Welt!"
]
]
];
echo getValueRecursive($foo, 'a', 'b', 'c'); // Returns "Hallo Welt!"
答案 0 :(得分:3)
<?php
$foo = [
'a' => [
'b' => [
'c' => "Hallo Welt!"
]
]
];
$result=array();
array_walk_recursive($foo, function($value,$key) use (&$result){
$result[]=$value;
});
print_r($result[0]);
或强>
<?php
ini_set("display_errors", 1);
$foo = [
'a' => [
'b' => [
'c' => "Hallo Welt!"
]
]
];
echo getValueOfArray($foo,"a","b","c");
function getValueOfArray($array)
{
$args=func_get_args();
unset($args[0]);
$string="";
foreach($args as $value)
{
$string.="['$value']";
}
eval('if(isset($array'.$string.'))
{
$result= $array'.$string.';
}');
return $result;
}
<强>输出:强>
Hallo Welt!
答案 1 :(得分:1)
前段时间我编写arrays library使用ArrayAccess
接口来实现此类操作。它不仅可以检索,还可以存储和删除值。
对于所有offset*()
方法,我使用了高阶方法walkThroughOffsets
:
protected function walkThroughOffsets(
&$array,
Callable $baseCaseAction,
Callable $offsetNotExistsAction
) {
$offset = array_shift($this->offsets);
if (is_scalar($offset) && isset($array[$offset])) {
if (empty($this->offsets)) {
return $baseCaseAction($array, $offset);
}
return $this->walkThroughOffsets(
$array[$offset],
$baseCaseAction,
$offsetNotExistsAction
);
}
return $offsetNotExistsAction($array, $offset);
}
使用此方法,您可以实现offsetGet
方法(当您尝试访问数组值时调用),如下所示:
public function offsetGet($offset)
{
$this->setOffsets($offset);
return $this->walkThroughOffsets(
$this->container,
function ($array, $offset) {
return $array[$offset];
},
$this->undefinedOffsetAction
);
}
然后你可以像通常的数组一样简单地得到值:
$array = new CompositeKeyArray([
'foo' => [
'bar' => 'baz'
]
]);
var_dump($array[['foo', 'bar']]); // => string(3) "baz"
var_dump($array[['foo', 'quux']]); // => PHP Fatal error: Uncaught UndefinedOffsetException: Undefined offset quux.
答案 2 :(得分:0)
您的方法与我推荐的方法非常相似。我想这基本上是一种“堆叠”技术,而不是对自定义函数进行条件/重复调用。我确实发现你的方法足够优雅。
调整:
null
),因此在提供无效键路径时随意return null
是不合适的。而是抛出异常,以便在调用函数的任何地方都可以区分结果。代码:(Demo) (Fringe Case)
function getValueRecursive(array $array, ...$keys) {
foreach ($keys as $key) {
if (!key_exists($key, $array)) {
throw new Exception('key path invalid');
}
$array = $array[$key];
}
return $array;
}
$foo = [
'a' => [
'b' => [
'c' => "Hallo Welt!"
]
]
];
try {
var_export(getValueRecursive($foo, 'a', 'b', 'c'));
echo "\n---\n";
var_export(getValueRecursive($foo, 'a', 'b'));
echo "\n---\n";
var_export(getValueRecursive($foo, 0, 'b', 'c'));
} catch (Exception $e) {
echo 'Caught exception: ' . $e->getMessage();
}
输出:
'Hallo Welt!'
---
array (
'c' => 'Hallo Welt!',
)
---
Caught exception: key path invalid