Rebol COLLECT:将源数据的顺序保持在循环中

时间:2014-02-16 14:39:57

标签: rebol rebol3 collect

有一些源数据,例如[1 2 3 4 "a" "b" "c" "d"],有四个项目作为一个组。我想在特定位置提取一些数据,例如每组的第一,第三和第四位。

有我的代码:

data: [1 2 3 4 "a" "b" "c" "d"]
output: copy []
foreach [p1 p2 p3 p4] data [ collect/into [keep p1 keep p3 keep p4] output ]
probe output    ;;the output is ["a" "c" "d" 1 3 4]

但我真正想要的是[1 3 4 "a" "c" "d"]。我该如何保留订单?

2 个答案:

答案 0 :(得分:3)

由于我不知道的原因,collect在内部使用insert,因此它会在开头插入数据,而不是在结尾插入append。我希望有人可以解释为什么会这样。同时,您可以使用优秀的repend来完成这项工作:

data: [1 2 3 4 "a" "b" "c" "d"]
output: copy []
forskip data 4 [repend output [data/1 data/3 data/4]]
probe output    ;; [1 3 4 "a" "c" "d"]

此外,在这种情况下最好使用forskip而不是foreach,因为您不必定义变量并仅通过索引访问。

答案 1 :(得分:3)

Rebol中使用/into选项的所有函数都使用insert语义。我们添加了这个选项,允许增量构建而无需制作尽可能多的中间系列,并允许您选择目标系列的类型,预分配以及各种其他功能用户技巧。 /into选项使用insert语义,因为insert不会丢失与append一样多的信息。

我们举个例子,但只使用collect

data: [1 2 3 4 "a" "b" "c" "d"]
output: collect [
    foreach [p1 p2 p3 p4] data [ keep p1 keep p3 keep p4 ]
]
probe output

这就是collect应该使编写更容易的简单代码。但它有点慢,所以让我们尝试使用/into

进行一些优化
data: [1 2 3 4 "a" "b" "c" "d"]
output: copy []
foreach [p1 p2 p3 p4] data [
    output: collect/into [keep p1 keep p3 keep p4] output
]
probe head output

这是/into代码的标准模型,并将按照您想要的顺序输出内容。但它实际上没有使用常规collect的任何优势,因为您没有预先分配目标块。这将节省重新分配:

data: [1 2 3 4 "a" "b" "c" "d"]
output: make block! 0.75 * length? data
foreach [p1 p2 p3 p4] data [
    output: collect/into [keep p1 keep p3 keep p4] output
]
probe head output

但是collect本身可能有点慢,因为它不是原生的;它主要是一种便利功能。幸运的是,我们有更快的本机函数,它们以相同的方式使用/into

data: [1 2 3 4 "a" "b" "c" "d"]
output: make block! 0.75 * length? data
foreach [p1 p2 p3 p4] data [ output: reduce/into [p1 p3 p4] output ]
probe head output

在那里没有使用非原生函数,这应该非常快。