如何优雅的跳出多层循环?

190 天前
 BIGBIG

如何优雅的跳出多层循环?

现有一个数据清洗任务。有多层循环,如下伪代码。 我的问题是:当 cleanedCount 达到 1 百万条数据时,要停止整个清洗任务。难道要一层一层 return 出去么?

class CleanData{

  // 已清洗数据量
  cleanedCount ;

  // 迁移任务
  method cleanByTask() {
    activityIdList.foreach{activityId -> cleanByActivity(activityId)}
  }

  // 按活动
  method cleanByActivity(activityId) {
    tables.foreach{table -> cleanByTable(table)}
  }

  // 按表
  method cleanByTable(table) {
    timeSplits.foreach{timeSplit -> cleanByTimeSplit(timeSplit)}
  }
  
  // 按时间切片
  method cleanByTimeSplit(timeSplit) {
    每 500 条.foreach{500 条 -> cleanByCount(500 条)}
  }

  // 按数量
  method cleanByCount(500 条) {
    cleanedCount += 500
    if (cleanedCount >= 1000000) {
      reurn;
    }
  }

}
3220 次点击
所在节点    Java
32 条回复
sockpuppet9527
190 天前
本身,引入一个状态机?或在 caller 那边做个状态?
chendy
190 天前
代码目测没啥问题
一层一层 reture 也没啥问题
难道楼主需要 System.exit(0) ?
elliottzhao87
190 天前
在外部放一个变量,检测变量直接在外层跳出呗?
xausky
190 天前
抛出个 Runtime 异常,最外层捕获处理,当然这个是旁门左道,正常还是多层 return 吧。
xwayway
190 天前
当然是 goto 啦,想去哪儿去哪儿
zhlxsh
190 天前
@xwayway 蒙多哈,想去哪就去哪
virusdefender
190 天前
抛出特定的异常
darkengine
190 天前
Java 的不知道啊。这个逻辑在 JS/TS 有问题,即使总数大于 1000000 也只是退出一个 foreach 代码块,没跑完的还是会空跑。
broken123
190 天前
@zhlxsh 就你最优秀
broken123
190 天前
直接问 chatgpt 即可
lsk569937453
190 天前
用 stream.flatMap.limit 完美解决
darkengine
190 天前
而且 foreach 空跑还会进入 cleanByCount ,现在的代码会导致 cleanedCount 不准确

method cleanByCount(500 条) {
cleanedCount += 500
if (cleanedCount >= 1000000) {
reurn;
}
}

改成
method cleanByCount(500 条) {
if (cleanedCount >= 1000000) {
reurn;
}
cleanedCount += 500
}
pengtdyd
190 天前
那当然是 kill -9 啦
cailinunix
190 天前
尝试扁平化你的数据,把多层循环拍平成一个迭代器,然后就可以随便跳出了
Aresxue
190 天前
所以说 goto 部分场景下还是有价值的。
针对这个场景用流也是个不错的方案。
nthin0
190 天前
我选择抛特定异常。。一层层 return 要加的判断比较多,有点丑陋
williamx
190 天前
绝大多数情况下,你这个是伪需求。每一层都有退出条件,退出时需要收尾,所以最内层退出后会自动一层层退出。

如果代码写得有漏洞 / 某些层条件没有配置好不能修改或者不想修改 / 想走特殊的逻辑而不是原来正常的逻辑,那就是异常情况,使用异常处理。
yazinnnn0
190 天前
java 有 goto 关键字, 但是这个关键字没有作用

有 break label 的语法, 但是你拆成多个函数就没办法用了

还是抛异常吧
GeruzoniAnsasu
190 天前
#7 +1:

method exceptionCaptured() {
try {cleanByTask()} catch(CountLimitExceeded){}
}

#4
> 抛出个 Runtime 异常,最外层捕获处理,当然这个是旁门左道,正常还是多层 return 吧。

不是旁门左道,这种不就是 recoverable exceptions, 抛异常是对的
Leviathann
190 天前
用 monad 的 flatMap

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

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

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

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

© 2021 V2EX