4

There is some source data, like [1 2 3 4 "a" "b" "c" "d"], four items as a group. I want to extract some data at specific positions, such as the first, third, and fourth from each group.

There is my code:

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]

But what I really want is [1 3 4 "a" "c" "d"]. How can I keep the order?

4

2 回答 2

4

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

那里没有使用非本机函数,这应该很快。

于 2014-02-16T23:54:36.337 回答
3

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

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在这种情况下使用,因为您不必定义变量并仅通过索引访问。

于 2014-02-16T14:53:23.987 回答