V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hpze2000
V2EX  ›  PHP

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

  •  
  •   hpze2000 · 2017-07-26 11:10:12 +08:00 · 3282 次点击
    这是一个创建于 2680 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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";

                    // 下面可能还有无限级	
                }    
            }
        }
    
    22 条回复    2017-07-26 17:14:51 +08:00
    hpze2000
        1
    hpze2000  
    OP
       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
        2
    webcoder  
       2017-07-26 11:17:04 +08:00
    如果是我作这个,肯定是用递归或 while。

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

    是递归还是 while,要从层级去决定,如果层级太多就用 while,递归的层级是有限的,太多就崩了。
    littleylv
        3
    littleylv  
       2017-07-26 11:19:19 +08:00
    不是能否,是必须
    hpze2000
        4
    hpze2000  
    OP
       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
        5
    gino86  
       2017-07-26 11:38:48 +08:00
    弄个 static 变量跟踪递归次数
    BoiledEgg
        6
    BoiledEgg  
       2017-07-26 11:42:14 +08:00
    递归方法搞个参数呗,每次调用方法这个参数+1,然后判断这个参数的值来退出递归就是了
    littleylv
        7
    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
        8
    fox0001  
       2017-07-26 11:57:21 +08:00 via Android
    PHP …看久了会眼花…
    hpze2000
        9
    hpze2000  
    OP
       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
        10
    hpze2000  
    OP
       2017-07-26 12:24:11 +08:00
    @littleylv 不行, 数据结构是上面那种
    jmc891205
        11
    jmc891205  
       2017-07-26 13:40:47 +08:00
    你可能有无限级 那怎么用递归啊 不会爆栈吗?

    自己搞一个栈模拟递归吧
    littleylv
        12
    littleylv  
       2017-07-26 13:56:47 +08:00
    @hpze2000 #10
    我试了你的数据 可以的啊
    feiyuanqiu
        13
    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
        14
    hpze2000  
    OP
       2017-07-26 15:28:55 +08:00
    @littleylv 确实不行, 我想要的是在 "2017-06-09" - 1 - 1 这层停止, 但是打印出来的结果还有再下一层的数据,  loop($dataArr, 1, 2); 是这样调用你代码吧?
    msg7086
        15
    msg7086  
       2017-07-26 15:49:32 +08:00
    自己维护一个 index 栈,模拟压栈弹栈操作吧。
    littleylv
        16
    littleylv  
       2017-07-26 16:03:25 +08:00   ❤️ 1
    @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
        17
    littleylv  
       2017-07-26 16:04:10 +08:00
    另外如果层级太大的话不要用递归了
    virusdefender
        18
    virusdefender  
       2017-07-26 16:05:02 +08:00
    抛异常?
    xqin
        19
    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
        20
    hpze2000  
    OP
       2017-07-26 16:24:42 +08:00
    设计是无限极,由客户端参数产生, 但是也没有 那么深的层次, 主要是只能用递归来实现逻辑
    @littleylv 恩, 可以使用,谢谢
    xqin
        21
    xqin  
       2017-07-26 16:36:43 +08:00
    你的数据 是 key/value 形式的, 直接 $xx[$yy][$zz] 不就能访问到那一层级的数据了? 要啥 递归?
    难道是这样?

    hpze2000
        22
    hpze2000  
    OP
       2017-07-26 17:14:51 +08:00
    @xqin 这些值都是动态的, 没有一个是明确的,而且层级也不确定 你这样不合适。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1040 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 21:58 · PVG 05:58 · LAX 13:58 · JFK 16:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.