打破R中的嵌套循环

Posted

技术标签:

【中文标题】打破R中的嵌套循环【英文标题】:Breaking out of nested loops in R 【发布时间】:2016-09-30 23:04:11 【问题描述】:

非常简单的示例代码(仅供演示,完全没用):

repeat 
  while (1 > 0) 
    for (i in seq(1, 100)) 
      break # usually tied to a condition
    
    break
  
  break

print("finished")

我想脱离多个循环而不在每个循环中分别使用break。 根据a similar question regarding python,将我的循环包装到一个函数中似乎是一种可能的解决方案,即使用return() 打破函数中的每个循环:

nestedLoop <- function() 
  repeat 
    while (1 > 0) 
      for (i in seq(1, 100)) 
        return()
      
    
  


nestedLoop()
print("finished")

R 中还有其他可用的方法吗?也许像标记循环然后指定要中断哪个循环(如在 Java 中)?

【问题讨论】:

我现在没有其他方法,会像这样使用return。但当然,我已经好几个月没写过嵌套的 R 循环了,也好几年没用过 R whilerepeat 循环了。 将循环包装到函数中的问题是,如果在其他地方需要,我可能必须从循环中返回大量变量以将它们放到全局环境中我的代码。 不,你的问题是使用了这么多循环。高效的 R 代码很少使用嵌套循环。 我们不是在谈论将性能发挥到极致,而是在时间上的数量级。 我想你会想要return something. 【参考方案1】:

使用显式标志,并根据这些标志有条件地中断循环可以提供更大的灵活性。示例:

stop = FALSE
for (i in c(1,2,3,4))
    for (j in c(7,8,9))
        print(i)
        print(j)
        if (i==3)
            stop = TRUE # Fire the flag, and break the inner loop
            break
        
        
    if (stop)break # Break the outer loop when the flag is fired
    

上面的代码会在i=3时打破两个嵌套循环。当最后一行 (if (stop)break) 被注释掉时,只有内部循环在i=3 处被破坏,但外部循环继续运行,即它实际上跳过了i=3 的情况。这种结构很容易使用,并且可以根据需要灵活。

【讨论】:

【参考方案2】:

我认为您将嵌套循环包装到函数中的方法是最干净且可能是最好的方法。你可以实际上在全局环境中调用return(),但是它会抛出一个错误并且看起来很丑,像这样:

for (i in 1:10) 
  for (a in 1:10) 
    for(b in 1:10) 

      if (i == 5 & a == 7 & b == 2)  return() 

    
  


print(i)
print(a)
print(b)

在命令行中如下所示:

> for (i in 1:10) 
+   for (a in 1:10) 
+     for(b in 1:10) 
+       
+       if (i == 5 & a == 7 & b == 2)  return() 
+       
+     
+   
+ 
Error: no function to return from, jumping to top level
> 
> print(i)
[1] 5
> print(a)
[1] 7
> print(b)
[1] 2

使用函数方法显然更好更简洁。

编辑:

添加了一种替代解决方案,以使 Roland 给出的错误看起来更好:

for (i in 1:10) 
  for (a in 1:10) 
    for(b in 1:10) 

      if (i == 5 & a == 7 & b == 2)  stop("Let's break out!") 

    
  


print(i)
print(a)
print(b)

【讨论】:

好吧,你可以直接使用simpleError 抛出错误。 simpleError("", call = return()) 替换return() 仍然会在控制台中引发错误,虽然我之前没有看到simpleError 所以我可能使用不正确。 试试stop("Let's break out!"),它返回一个simpleError对象。 在替代版本中添加,是这个意思吗? 是的,这比使用仅因为您想要错误而引发错误的表达式/函数要好。当然,这仍然不是一个好的解决方案,因为这不是正确使用错误。如果将此代码包装在一个函数中,您就会明白为什么。您无法从该函数获得返回值。

以上是关于打破R中的嵌套循环的主要内容,如果未能解决你的问题,请参考以下文章

如何打破 Dart 中的嵌套循环

如何打破 Objective-C 中的两个嵌套 for 循环?

Python打破嵌套的for循环并重新启动while循环

打破嵌套循环[重复]

打破 JavaScript 中嵌套循环的最佳方法是啥?

打破嵌套循环和主循环[重复]