我走过一组嵌套的街区,想要在找到我正在寻找的价值时停止走路。
由于超出此问题范围的原因,我不能将PARSE用于此特定问题,也不能将FOREACH用作looper:
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口味解决这个问题。任何关于效率的想法(我使用块而不是函数的原因)等也会受到欢迎。
答案 0 :(得分:2)
我正在寻找的功能组合是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
我只是让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
]
]
]
这引入了一个复杂因素,因为我只希望将块绑定到单词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
答案 1 :(得分:2)
此版本避免绑定除VALUE之外的任何内容,并在Red 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也没有。我认为这是一个很小的问题。