recursion - 打破递归函数

标签 recursion rebol rebol3 rebol2 red

我正在遍历一组嵌套 block ,并希望在找到我要查找的值时停止遍历。

由于超出了这个问题范围的原因,我不能使用 PARSE 来解决这个特定问题,也不能使用 FOREACH 作为循环器:

walk: func [series [block!] criteria [block!]][
    use [value] compose/deep [
        while [not tail? series][
            value: pick series 1

            either block? value [
                walk value criteria
            ][
                (to paren! criteria)
            ]

            series: next series
        ]
    ]
]

如果我找到这个特定值,我想突破。

walk [a [b c [d e] f] g] [if value = 'e [return value]]
; returns 'e

但是,我也想做一些不会爆发的操作:

walk [a [b c [d e] f] g] [
    collect [if find [c e] value [keep value]]
]
; returns [c e]

想尝试解决包括 Red 在内的任何 Rebol 口味的问题。任何关于效率的想法(我使用 block 而不是函数的原因)等也将受到欢迎。

最佳答案

我正在寻找的功能组合是 CATCH/THROW。再次使用给定的函数:

walk: func [series [block!] criteria [block!]][
    use [value] compose/deep [
        while [not tail? series][
            value: pick series 1

            either block? value [
                walk value criteria
            ][
                (to paren! criteria)
            ]

            series: next series
        ]
    ]
]

我可以简单地将其包装如下:

catch [walk [a [b c [d e] f] g] [if value = 'e [throw value]]]
; returns 'e

一些注释

  • 如果没有匹配项,我希望函数返回 NONE

我会让 WALK 返回 NONE (我使用 ALSO 只是为了不留下尴尬的尾部 none):

 walk: func [series [block!] criteria [block!]][
      also none use [value] compose/deep [
          while [not tail? series][
              value: pick series 1

              either block? value [
                  walk value criteria
              ][
                  (to paren! criteria)
              ]

              series: next series
          ]
      ]
  ]
  • 没有USE功能

这会带来麻烦,因为我只想将 block 绑定(bind)到单词 VALUE。如果我将函数重写如下:

walk: func [series [block!] criteria [block!] /local value][
    do bind compose/deep [
        while [not tail? series][
            value: pick series 1

            either block? value [
                walk value criteria
            ][
                (to paren! criteria)
            ]

            series: next series
        ]
    ] 'value
]

然后,它还将同一 block 绑定(bind)到单词 SERIES 和 CRITERIA,这将覆盖调用上下文中任何此类单词的绑定(bind),例如:

walk [some values][series: none probe value] ; results in error

关于recursion - 打破递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44913817/

相关文章:

python - threading.Timer如何避免Python中的递归?

recursion - Rebol 尾调用优化

javascript - 父值作为嵌套 javascript 对象中所有子值的总和

java - 大 O 与递归

c++ - 拜特兰金币

rebol - 如何忽略解析时注释掉的行?

function - 为什么在 REBOL 中函数 "have memory"?

ssl - 什么可能是这个 : ** Command Error: SSL Error: error:14077410:SSL routines:SSL23_GET_SERVER_HEL LO:sslv3 alert handshake failure 的原因

Rebol 3 r3gui 有哪些可用的边框效果?

garbage-collection - 为什么 map-each 会保留引用要设置的单词的最后一个值?