有一些源数据,例如[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"]
。我该如何保留订单?
答案 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
在那里没有使用非原生函数,这应该非常快。