动态访问多维数组值
Posted
技术标签:
【中文标题】动态访问多维数组值【英文标题】:Dynamically accessing multidimensional array value 【发布时间】:2016-07-19 23:30:46 【问题描述】:我正在尝试查找(或创建)一个函数。我有一个多维数组:
$data_arr = [
"a" => [
"aa" => "abfoo",
"ab" => [
"aba" => "abafoo",
"abb" => "abbfoo",
"abc" => "abcfoo"
],
"ac" => "acfoo"
],
"b" => [
"ba" => "bafoo",
"bb" => "bbfoo",
"bc" => "bcfoo"
],
"c" => [
"ca" => "cafoo",
"cb" => "cbfoo",
"cc" => "ccfoo"
]
];
我想使用一维数组访问一个值,如下所示:
$data_arr_call = ["a", "ab", "abc"];
someFunction( $data_arr, $data_arr_call ); // should return "abcfoo"
这似乎已经有这种类型的功能,我只是不知道要搜索什么。
【问题讨论】:
你的意思是访问$data_arr['a']['ab']['abc']
?
对...它几乎需要['a', 'ab', 'abc']
并认识到它的意思是$data_arr['a']['ab']['abc']
【参考方案1】:
试试这个
function flatCall($data_arr, $data_arr_call)
$current = $data_arr;
foreach($data_arr_call as $key)
$current = $current[$key];
return $current;
OP的解释:
$current
变量被迭代构建,如下所示:
flatCall($data_arr, ['a','ab','abc']);
1st iteration: $current = $data_arr['a'];
2nd iteration: $current = $data_arr['a']['ab'];
3rd iteration: $current = $data_arr['a']['ab']['abc'];
您还可以在每次迭代中执行if ( isset($current) ) ...
以提供错误检查。
【讨论】:
缺少$key
,它在哪里拉它?哦,我想你的意思是$data_arr_call as $key
@philtune 是的,完全正确
虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!
是的,我知道为什么会这样,但就像@Rizier123 所说,你应该写一个解释,我会接受这个答案。谢谢。
@Rizier123 我确信这 3 行简单的代码不需要任何解释。如果你不同意,你可以自己做。【参考方案2】:
你可以使用这个函数来避免整个数组的复制(使用引用),能够返回一个 NULL 值(使用array_key_exists
而不是isset
),并且当路径没有时抛出异常'存在:
function getItem(&$array, $path)
$target = &$array;
foreach($path as $key)
if (array_key_exists($key, $target))
$target = &$target[$key];
else throw new Exception('Undefined path: ["' . implode('","', $path) . '"]');
return $target;
演示:
$data = [
"a" => [
"aa" => "abfoo",
"ab" => [
"aba" => "abafoo",
"abb" => NULL,
"abc" => false
]
]
];
var_dump(getItem($data, ['a', 'ab', 'aba']));
# string(6) "abafoo"
var_dump(getItem($data, ['a', 'ab', 'abb']));
# NULL
var_dump(getItem($data, ['a', 'ab', 'abc']));
# bool(false)
try
getItem($data, ['a', 'ab', 'abe']);
catch(Exception $e)
echo $e->getMessage();
# Undefined path: ["a","ab","abe"]
注意这个功能可以改进,比如可以测试参数是不是数组。
【讨论】:
【参考方案3】:想发布一个更优雅的解决方案:array_reduce
$data_arr = [
"a" => [
...
"ab" => [
...
"abc" => "abcfoo"
],
...
],
...
];
$result = array_reduce(["a", "ab", "abc"], function($a, $b)
return $a[$b];
, $data_arr);
// returns "abcfoo"
我最近一直在使用 javascript 的 Array.reduce()
将一些遗留代码更新为 ES6:
JS:
const data_obj = ...;
let result = ['a','ab','abc'].reduce((a, b) => a[b], data_obj);
【讨论】:
【参考方案4】:你需要这样的函数:
function getValue($data_arr, $data_arr_call)
foreach ($data_arr_call as $index)
if (isset($data_arr[$index]))
$data_arr = $data_arr[$index];
else
return false;
return $data_arr;
并像这样使用它:
$data_arr = [
"a" => [
"ab" => [
"abc" => "abbfoo",
],
],
];
$data_arr_call = ["a", "ab", "abc"];
$value = getValue($data_arr, $data_arr_call);
if ($value)
// do your stuff
【讨论】:
以上是关于动态访问多维数组值的主要内容,如果未能解决你的问题,请参考以下文章