我有以下(json)对象:
$obj = json_decode('{
"Group1": {
"Blue": {
"Round": [
"Harold",
"Arthur",
"Tom"
]
},
"Green": {
"Round": [
"Harold"
],
"Circle": [
"Todd",
"Mike"
]
}
},
"Group2": {
"Blue": {
"Round": [
"Peter"
]
}
}
}', true);
我正在试图弄清楚如何递归遍历它,这样我就可以看到数组中的所有不同路径。
它可以是4个独立的回声或4行的回声。 >
可以替换为任何内容或根本不替换。如果每一行都单独回显或推送到一个可能提供最大灵活性的数组。
Group1 - Blue - Round - (Harold, Arthur, Tom)
Group1 - Green - Round - (Harold)
Group1 - Green - Circle - (Todd, Mike)
Group2 - Blue - Round - (Peter)
我无法绕过它,所以任何帮助都会受到赞赏。
我想我可以以某种方式循环每个人:
foreach($obj as $index => $value)
{
// and then somehow do this until you reach an array?
}
答案 0 :(得分:6)
答案 1 :(得分:2)
这适用于阵列的不同深度,请检查live demo。
while(count($array) != count($array, 1)) // stop when $array is one dimension
{
$temp = [];
foreach($array as $k => $v)
{
if(is_array($v))
{
if(count($v) != count($v, 1)) // check if reached the inner most array
{
foreach($v as $kk => $vv)
{
$temp[$k . ' - ' . $kk] = $vv;
}
}
else
$temp[$k] = '(' . implode($v, ', ') . ')';
}else
$temp[$k] = $v;
}
$array = $temp;
}
foreach($array as $k => $v)
echo $k . ' - ' . $v . "\n";
注意:强>
traverse array from outer to inner
traverse array from inner to outer
答案 2 :(得分:2)
我创建了简单的递归函数。对于你的例子。将以前的键值存储在一个变量中,并根据前一个键添加所有数据并创建新数组(其中包含所有以前的键作为索引,最后一个元素作为值)。请尝试以下代码:
$obj = json_decode('{
"Group1": {
"Blue": {
"Round": [
"Harold",
"Arthur",
"Tom"
]
},
"Green": {
"Round": [
"Harold"
],
"Circle": [
"Todd",
"Mike"
]
}
},
"Group2": {
"Blue": {
"Round": [
"Peter"
]
}
}
}', true);
function traverse_array($array,$key="",$prev="",&$final_op=array())
{
if(is_array($array))
{
$prev .= $key." - ";
foreach ($array as $key => $value) {
traverse_array($value,$key,$prev,$final_op);
}
}
else
{
$prev =trim($prev," - ");
$final_op[$prev][]=$array;
}
return $final_op;
}
$data = traverse_array($obj);
foreach ($data as $key => $value) {
echo $key." (".implode(",", $value).")";
echo PHP_EOL;
}
答案 3 :(得分:0)
试试这个
我创建了可以调整的样本递归程序
$obj = json_decode('{"Group1": {
"Blue": {
"Round": [
"Harold",
"Arthur",
"Tom"
]
},
"Green": {
"Round": [
"Harold"
],
"Circle": [
"Todd",
"Mike"
]
}
},
"Group2": {
"Blue": {
"Round": [
"Peter"
]
}
}
}');
recursive($obj);
function recursive($obj){
if(is_array($obj)){
foreach ($obj as $k => $v) {
echo $v." ";
}
return;
}
foreach ($obj as $key => $value) {
echo $key. " =>";
recursive($value);
}
echo "\n";
}
以下是样本输出
Group1 =>Blue =>Round =>Harold Arthur Tom
Green =>Round =>Harold Circle =>Todd Mike
Group2 =>Blue =>Round =>Peter
答案 4 :(得分:0)
我把我的方法简化为非常简单易读的东西。请参阅内联注释以获取解释。我有两个版本:一个4行回显函数和一个数组返回函数。
*请注意,此方法特别针对此问题而构建,因为:
方法#1 - 从函数内部回显字符串:(Demo)
$array=json_decode('{
"Group1": {
"Blue": {
"Round": {
"One": [
"Lawrence",
"Anant",
"B."
],
"Two": [
"Erwin"
]
}
},
"Green": [
"Bryan",
"Mick"
]
},
"Group2": [
"Peter",
"Kris"
]
}', true);
function recurse($array,$path=''){
foreach($array as $k=>$v){
if(!is_array(current($v))){ // check type of the first sub-element's value
echo ($path?"$path > ":''),"$k > (".implode(', ',$v).")\n"; // don't recurse, just implode the indexed elements
}else{ // recurse because at least 2 levels below
recurse($v,($path?"$path > $k":$k)); // build path appropriately
}
}
}
recurse($array);
输出:
Group1 > Blue > Round > One > (Lawrence, Anant, B.)
Group1 > Blue > Round > Two > (Erwin)
Group1 > Green > (Bryan, Mick)
Group2 > (Peter, Kris)
方法#2 - 返回4个元素的路径数组:(Demo)
function recurse($array,$path='',&$result=[]){
foreach($array as $k=>$v){
if(!is_array(current($v))){ // check type of the first sub-element's value
$result[]=($path?"$path > ":'')."$k > (".implode(', ',$v).')'; // don't recurse, just implode the indexed elements
}else{ // recurse because at least 2 levels below
recurse($v,($path?"$path > ":'').$k,$result); // build path appropriately
}
}
return $result;
}
var_export(recurse($array));
输出:
array (
0 => 'Group1 > Blue > Round > One > (Lawrence, Anant, B.)',
1 => 'Group1 > Blue > Round > Two > (Erwin)',
2 => 'Group1 > Green > (Bryan, Mick)',
3 => 'Group2 > (Peter, Kris)',
)
最后一次更新:
我能给出的最好的建议是删除这个中间步骤并将your raw/initial json string转换为新的所需输出(不需要递归/堆叠):
代码:(Demo)
$seperateArray = json_decode('[
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "One", "tier5": "Lawrence" },
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "One", "tier5": "Anant" },
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "One", "tier5": "B." },
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Two", "tier5": "Erwin" },
{ "tier1": "Group1", "tier2": "Green", "tier3": "Bryan" },
{ "tier1": "Group1", "tier2": "Green", "tier3": "Mick" },
{ "tier1": "Group2", "tier2": "Peter" },
{ "tier1": "Group2", "tier2": "Kris" }]',true);
foreach($seperateArray as $row){
$last_val=current(array_splice($row,-1)); // extract last element, store as string
$results[implode(' > ',$row)][]=$last_val;
}
foreach($results as $k=>$v){
echo "$k > (",implode(', ',$v),")\n";
}
// same output as earlier methods
答案 5 :(得分:0)
这是我对发电机功能的看法:
function paths(array $a)
{
// if first item is an array, recurse
if (is_array(reset($a))) {
foreach ($a as $k => $v) {
foreach (paths($v) as $path) {
// yield "key - subpath"
yield sprintf('%s - %s', $k, $path);
}
}
} else {
// yield leaf
yield sprintf('(%s)', implode(', ', $a));
}
}
foreach (paths($obj) as $path) {
printf("%s\n", $path);
}
试试online。