问题描述
我想通过 foreach
修改块的每个元素。我试过这样但失败了:
>> a: [3 4 5 6]
== [3 4 5 6]
>> foreach i a [i + 1]
== 7
>> a
== [3 4 5 6] ;; block a is not changed. What I want is [4 5 6 7]
有没有更好的方法来实现它?
解决方法
您对值所做的更改不会保留在块本身中。这与您关于在 Rebol 和 Red 中按值调用参数传递的 question 相关联:您修改堆栈上的 copy(向下传递到 +
以及 {{ 1}}),而不是位于块 1
内的实际值槽。
要实现您想要的,您需要就地递增整数,而不是将它们压入堆栈。一种方法是使用 a
。
forall
>> block: [1 2 3]
== [1 2 3]
>> also block forall block [block/1: block/1 + 1]
== [2 3 4]
的作用是将一个词设置为一个系列,然后逐步增加其索引:
forall
由于它不提取实际值,您可以使用路径表示法访问它们,然后就地修改它们。 >> forall block [probe block]
[1 2 3]
[2 3]
[3]
总是在每次迭代时选择第一个值。
>> help forall
USAGE:
FORALL 'word body
DESCRIPTION:
Evaluates body for all values in a series.
FORALL is a native! value.
ARGUMENTS:
'word [word!] "Word referring to series to iterate over."
body [block!]
全部使用
> a: [3 4 5 6]
== [3 4 5 6]
>> forall a [a/1: a/1 + 1]
== 7
>> probe a
[4 5 6 7]
== [4 5 6 7]
,
像往常一样,您的 foreach 没有回复。
a: [2 3 4 5]
b: copy []
foreach i a [append b i + 1]
如果您愿意,现在可以将 a 设置为 b
a: b
一步完成的问题是你没有可以在这里使用的索引(尽管有暗示性的字母 i,但它代表了块内每个项目的内容)。
现在您可以选择自己喜欢的解决方案。