【问题标题】:Breaking/Continuing nested for loops in Coffeescript在 Coffeescript 中中断/继续嵌套的 for 循环
【发布时间】:2011-12-01 03:08:36
【问题描述】:

如何在 Coffeescript 中中断/继续嵌套循环?例如。我有类似的东西:

for cat in categories
  for job in jobs
    if condition
      do(this)
      ## Iterate to the next cat in the first loop

另外,有没有办法将整个第二个循环包装为第一个循环中另一个函数的条件?例如。

for cat in categories
  if conditionTerm == job for job in jobs
    do(this)
    ## Iterate to the next cat in the first loop
  do(that) ## Execute upon eliminating all possibilities in the second for loop,
           ## but don't if the 'if conditionTerm' was met

【问题讨论】:

    标签: coffeescript


    【解决方案1】:

    使用带有返回的匿名循环

    do ->
      for a in A
        for b in B 
          for c in C
            for d in D
              for e in E
                for f in F
                  for g in G
                    for h in H
                      for i in I
                        #DO SOMETHING
                        if (condition)
                          return true
    

    【讨论】:

    • 这令人印象深刻,甚至看起来很漂亮,但我不确定它为公认的最佳答案增加了什么。
    • 这确实是在 CoffeeScript 中正确解决这种情况的方法——将你的代码组织成一个子函数,以便函数 return 打破你需要打破的最外层循环——否则你就是无论如何都要创建意大利面条代码。这也一定是 CoffeeScript 中没有标签的设计原因。
    【解决方案2】:

    为了检查数组中的所有元素,lodash 的every 可能有用吗?

    https://lodash.com/docs#every

    for cat in categories
      if _.every jobs, conditionTerm
    ...
    

    【讨论】:

      【解决方案3】:

      Coffeescript 永远不会有多个中断/继续语句,您必须坚持使用丑陋和过多的标志来污染您的代码,或者尝试用 lambda 替换 do 并使用 return 作为多个中断。

      https://github.com/jashkenas/coffeescript/issues/4254

      【讨论】:

        【解决方案4】:

        如果您想使用内部中断/继续,我想您的代码设计不是很好。 在我看来,任何编程语言都不允许这样做。

        按照别人的建议使用标签也被认为是不好的风格。

        【讨论】:

        • 除非你提供一个重构的例子来证明你的观点,否则这并不是一个公平的说法
        • 好吧,1) 标签永远都不好。他们创建了意大利面条式的代码 2)由于双重中断不可用,因此可以始终使用内部条件,正如上面 Mark Parson 的回答中所述。
        • 这是一个基于语义的教条主义主张。并非所有称为“标签”的东西都是一样的。
        • 两级断层简洁优雅。
        • 请考虑添加代码以说明您的索赔理由。仅仅说“不好”并不能提供有用的反馈。
        【解决方案5】:

        break 和 js 一样工作:

        for cat in categories
          for job in jobs
            if condition
              do this
              break ## Iterate to the next cat in the first loop
        

        你的第二种情况不是很清楚,但我假设你想要这个:

        for cat in categories
            for job in jobs
              do this
              condition = job is 'something'
            do that unless condition
        

        【讨论】:

        • 谢谢 Ricardo,不知道 break。但是,将条件放在 if 语句中是行不通的,因为“job”在下面的“job in jobs”行中定义,对吗?
        【解决方案6】:

        Coffescript 的“break”只会中断直接循环,并且无法识别外部循环是否损坏(烦人!)。在某些情况下,以下 hack 可以在满足条件时打破多个循环:

        ar1 = [1,2,3,4]
        ar2 = [5,6,7,8]
        
        for num1 in ar1
          for num2 in ar2
            console.log num1 + ' : ' + num2
            if num2 == 6
              breakLoop1 = true; break 
          break if breakLoop1
        
        # Will print:
        # 1 : 5
        # 1 : 6
        

        【讨论】:

        • JavaScript 实际上支持使用 labels 打破外部循环,但为了在 CoffeeScript 中执行此操作,您需要 @matyr 的答案中描述的 hack。
        【解决方案7】:

        使用labels。由于 CoffeeScript 不支持它们,你需要这样破解:

        0 && dummy
        `CAT: //`
        for cat in categories
          for job in jobs
            if conditionTerm == job
              do this
              `continue CAT` ## Iterate to the next cat in the first loop
          do that ## Execute upon eliminating all possibilities in the second for loop,
                  ## but don't if the 'if conditionTerm' was met
        

        【讨论】:

        • 谢谢!救了我的命:)
        • (CoffeeScriptRedux 不支持)
        • @AndreyM 不。您可以将标签视为本质上为循环命名。当您使用标签中断时,您不会转到 到带标签的行 - 您正在使用指定名称中断循环。见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
        • 正是我需要的。谢谢!您可能会认为 CoffeeScript 允许 :: 之类的东西告诉编译器您的意思是显式标签,而不是对象文字。例如,topLoop:: for i in names 脱糖为topLoop: for(var i = 0; …)。反引号并不总是可能的,如some projects blacklist them
        • 此外,如果 CoffeeScript 在循环和 hack 之间插入中间赋值,这将不起作用。例如,`NAME: //` ⮒ for key, value of @hash 编译为NAME: //; ⮒ ref = this.hash; ⮒ for(key in ref){,这显然是行不通的(⮒ 表示示例代码中的换行符)。一种解决方法是自己提供中间参考:ref = @hash; `NAME: //` ⮒ for key, value of ref
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-27
        • 1970-01-01
        • 2021-12-27
        • 2010-11-11
        • 1970-01-01
        • 2021-03-28
        • 1970-01-01
        相关资源
        最近更新 更多