打破递归函数



我正在遍历一组嵌套块,当我找到我正在寻找的值时,我想停止走动。

由于超出此问题范围的原因,我不能对这个特定问题使用 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]

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

我一直在寻找的函数组合是 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(我也使用 JUST 是为了不留下尴尬的尾随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 函数

这带来了一个复杂性,因为我只想将块绑定到单词 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
]

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

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

此版本避免绑定除 VALUE 以外的任何内容,适用于红色 0.6.3 和 Rebol2:

walk: func [series [block!] criteria [block!]][
also none do bind compose/deep [
while [not tail? series] [
value: pick series 1
either block? value [
walk value criteria
] [
(to paren! criteria)
]
series: next series
]
]
context [value: none]
]

(欢迎评论此实现与USE功能的不同之处。

是的,这在 Rebol3 Alpha 上不起作用。但是使用USE的人也没有。我认为这是一个抛掷问题。

相关内容

  • 没有找到相关文章

最新更新