这个能否改成递归, 并在指定层级退出循环

2017-07-26 11:10:12 +08:00
 hpze2000

foreach ($dataArr as $key1 => $da1) {
echo 'lay1 * ' . $key1 . ": " . count($da1) . "\n"; foreach ($da1 as $key2 => $da2) { echo 'lay2 * ' . $key2 . ": " . count($da2) . "\n"; foreach ($da2 as $key3 => $da3) { echo 'lay3 * ' . $key3 . ": " . count($da3) . "\n";

                // 下面可能还有无限级	
            }    
        }
    }
3276 次点击
所在节点    PHP
22 条回复
hpze2000
2017-07-26 11:12:06 +08:00
foreach ($dataArr as $key1 => $da1) {
echo 'lay1 * ' . $key1 . ": " . count($da1) . "\n";
foreach ($da1 as $key2 => $da2) {
echo 'lay2 * ' . $key2 . ": " . count($da2) . "\n";
foreach ($da2 as $key3 => $da3) {
echo 'lay3 * ' . $key3 . ": " . count($da3) . "\n";

// 可能有无限极, 能在指定层这里跳出循环
}
}
}
webcoder
2017-07-26 11:17:04 +08:00
如果是我作这个,肯定是用递归或 while。

人超级懒,超过两个以上的重复代码都是懒得写了,而且你这还是不定级的,要不递归,要不 while。

是递归还是 while,要从层级去决定,如果层级太多就用 while,递归的层级是有限的,太多就崩了。
littleylv
2017-07-26 11:19:19 +08:00
不是能否,是必须
hpze2000
2017-07-26 11:32:31 +08:00
function loop($data) {
if (!is_array($data)) return;

foreach ($data as $key1 => $da1) {
echo $key1 . ": " . count($da1) . "\n";
loop($da1);

// 这样递归, 怎么在 第三层的时候跳出 总共可能有 10 层
}
}
gino86
2017-07-26 11:38:48 +08:00
弄个 static 变量跟踪递归次数
BoiledEgg
2017-07-26 11:42:14 +08:00
递归方法搞个参数呗,每次调用方法这个参数+1,然后判断这个参数的值来退出递归就是了
littleylv
2017-07-26 11:44:40 +08:00
function loop($data, $now=1, $break=0) {
foreach ($data as $key => $val) {
echo $key . ": " . count($val) . "\n";
if(is_array($val) && ($break==0 || $now <= $break)){
loop($val, $now++, $break);
}
}
}

试试咯
fox0001
2017-07-26 11:57:21 +08:00
PHP …看久了会眼花…
hpze2000
2017-07-26 12:23:42 +08:00
``` json
{"2017-06-09":{"1":{"1":{"1009":[["2017-06-09","1","1","1009","58950.0"]],"1013":[["2017-06-09","1","1","1013","56313.0"]],"1014":[["2017-06-09","1","1","1014","28712.0"]],"1018":[["2017-06-09","1","1","1018","28066.0"]],"1019":[["2017-06-09","1","1","1019","21876.0"]],"1024":[["2017-06-09","1","1","1024","1726.0"]]},"2":{"1009":[["2017-06-09","1","2","1009","155460.0"]],"1013":[["2017-06-09","1","2","1013","161308.0"]],"1014":[["2017-06-09","1","2","1014","85232.0"]],"1018":[["2017-06-09","1","2","1018","76618.0"]],"1019":[["2017-06-09","1","2","1019","86616.0"]],"1024":[["2017-06-09","1","2","1024","20397.0"]]},"3":{"1009":[["2017-06-09","1","3","1009","37313.0"]],"1013":[["2017-06-09","1","3","1013","21614.0"]],"1014":[["2017-06-09","1","3","1014","31182.0"]],"1018":[["2017-06-09","1","3","1018","32203.0"]],"1019":[["2017-06-09","1","3","1019","25704.0"]],"1024":[["2017-06-09","1","3","1024","4950.0"]]},"4":{"1009":[["2017-06-09","1","4","1009","13948.0"]],"1013":[["2017-06-09","1","4","1013","13140.0"]],"1014":[["2017-06-09","1","4","1014","6991.0"]],"1018":[["2017-06-09","1","4","1018","10775.0"]],"1019":[["2017-06-09","1","4","1019","7691.0"]],"1024":[["2017-06-09","1","4","1024","736.0"]]},"5":{"1009":[["2017-06-09","1","5","1009","344285.0"]],"1013":[["2017-06-09","1","5","1013","280339.0"]],"1014":[["2017-06-09","1","5","1014","237754.0"]],"1018":[["2017-06-09","1","5","1018","223571.0"]],"1019":[["2017-06-09","1","5","1019","219879.0"]],"1024":[["2017-06-09","1","5","1024","25673.0"]]},"6":{"1009":[["2017-06-09","1","6","1009","96828.0"]],"1013":[["2017-06-09","1","6","1013","103464.0"]],"1014":[["2017-06-09","1","6","1014","49379.0"]],"1018":[["2017-06-09","1","6","1018","62153.0"]],"1019":[["2017-06-09","1","6","1019","39691.0"]],"1024":[["2017-06-09","1","6","1024","5976.0"]]}},"2":{"1":{"1009":[["2017-06-09","2","1","1009","573576.0"]],"1013":[["2017-06-09","2","1","1013","558571.0"]],"1014":[["2017-06-09","2","1","1014","323552.0"]],"1018":[["2017-06-09","2","1","1018","304721.0"]],"1019":[["2017-06-09","2","1","1019","320235.0"]],"1024":[["2017-06-09","2","1","1024","50228.0"]]},"2":{"1009":[["2017-06-09","2","2","1009","97358.0"]],"1013":[["2017-06-09","2","2","1013","84935.0"]],"1014":[["2017-06-09","2","2","1014","57710.0"]],"1018":[["2017-06-09","2","2","1018","37856.0"]],"1019":[["2017-06-09","2","2","1019","59515.0"]],"1024":[["2017-06-09","2","2","1024","12598.0"]]},"3":{"1009":[["2017-06-09","2","3","1009","14631.0"]],"1013":[["2017-06-09","2","3","1013","15582.0"]],"1014":[["2017-06-09","2","3","1014","12144.0"]],"1018":[["2017-06-09","2","3","1018","12527.0"]],"1019":[["2017-06-09","2","3","1019","14618.0"]],"1024":[["2017-06-09","2","3","1024","1859.0"]]},"4":{"1009":[["2017-06-09","2","4","1009","8131.0"]],"1013":[["2017-06-09","2","4","1013","3090.0"]],"1014":[["2017-06-09","2","4","1014","7888.0"]],"1018":[["2017-06-09","2","4","1018","7041.0"]],"1019":[["2017-06-09","2","4","1019","5873.0"]],"1024":[["2017-06-09","2","4","1024","1054.0"]]},"5":{"1009":[["2017-06-09","2","5","1009","197357.0"]],"1013":[["2017-06-09","2","5","1013","168221.0"]],"1014":[["2017-06-09","2","5","1014","141942.0"]],"1018":[["2017-06-09","2","5","1018","159086.0"]],"1019":[["2017-06-09","2","5","1019","145580.0"]],"1024":[["2017-06-09","2","5","1024","16738.0"]]},"6":{"1009":[["2017-06-09","2","6","1009","11851.0"]],"1013":[["2017-06-09","2","6","1013","8199.0"]],"1014":[["2017-06-09","2","6","1014","7198.0"]],"1018":[["2017-06-09","2","6","1018","6964.0"]],"1019":[["2017-06-09","2","6","1019","5844.0"]],"1024":[["2017-06-09","2","6","1024","-151.0"]]}}}}
```
hpze2000
2017-07-26 12:24:11 +08:00
@littleylv 不行, 数据结构是上面那种
jmc891205
2017-07-26 13:40:47 +08:00
你可能有无限级 那怎么用递归啊 不会爆栈吗?

自己搞一个栈模拟递归吧
littleylv
2017-07-26 13:56:47 +08:00
@hpze2000 #10
我试了你的数据 可以的啊
feiyuanqiu
2017-07-26 14:19:46 +08:00
慎用递归...小心爆栈

function loop(array $data, callable $consumer, int $i = 0)
{
foreach ($data as $k => $v) {
if (!$consumer($k, $v, $i++)) {
break;
}
if (is_array($v)) {
loop($v, $consumer, $i);
}
}
}

function printCount($k, $v, $i)
{
echo "layer{$i} * {$k}: " . count($v) . "\n";
return $i < 10;
}

$a = [];
loop($a, 'printCount');
hpze2000
2017-07-26 15:28:55 +08:00
@littleylv 确实不行, 我想要的是在 "2017-06-09" - 1 - 1 这层停止, 但是打印出来的结果还有再下一层的数据,  loop($dataArr, 1, 2); 是这样调用你代码吧?
msg7086
2017-07-26 15:49:32 +08:00
自己维护一个 index 栈,模拟压栈弹栈操作吧。
littleylv
2017-07-26 16:03:25 +08:00
@hpze2000 #14

sorry

function loop($data, $now = 0, $break = 0) {
foreach ($data as $key => $val) {
if (is_array($val) && ($break == 0 || $now <= $break)) {
for ($n = 0; $n < $now; $n++) {
echo '-';
}
echo $key . ': ' . count($val) . PHP_EOL;
loop($val, $now + 1, $break);
}
}
}
loop($b, 0, 2);

递归那里应该是$now + 1 而不是 $now++

打印结果:
2017-06-09: 2
-1: 6
--1: 6
--2: 6
--3: 6
--4: 6
--5: 6
--6: 6
-2: 6
--1: 6
--2: 6
--3: 6
--4: 6
--5: 6
--6: 6
littleylv
2017-07-26 16:04:10 +08:00
另外如果层级太大的话不要用递归了
virusdefender
2017-07-26 16:05:02 +08:00
抛异常?
xqin
2017-07-26 16:16:32 +08:00
话说楼主这数据怎么生成的? 我比较好奇.
你的数据里面, 最深的那层里的那个数组, 前面记录的就是你的进入路径..



根据你目前的数据来看, 你只需要根据你要的东西, 直接去取 相应下标的内容即可...

比如像下面这样:


像你上面说的,你需要 `"2017-06-09" - 1 - 1` 停止, 那么你直接使用 `$d['2017-06-09']['1']['1']` 不就得到这一层了吗? (PS: json_decode 的时候传递第二个参数, 值为 true, 以便让它返回 数组)
要啥循环,要啥递归?
hpze2000
2017-07-26 16:24:42 +08:00
设计是无限极,由客户端参数产生, 但是也没有 那么深的层次, 主要是只能用递归来实现逻辑
@littleylv 恩, 可以使用,谢谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/378026

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX