如何在 Rebol 2 中对列表进行分区
How to partition a list in Rebol 2
如何在 Rebol 2 中对列表进行分区?我不关心分区的最终顺序。
例如我想象会有这样的功能:
lst: [1 5 6 5 5 2 1 3]
probe partition lst ; Assuming identity function by default
[[1 1] [5 5 5] [6] [2] [3]]
probe partition/by lst even?
[[6 2] [1 5 5 5 1 3]]
如果没有这样的内置函数,在 Rebol 中构造它的惯用方法是什么?
rebol.org/scripts/hof 上有一些 HOF,
例如实现你第二个愿望的配分函数
partition: func [
{Partition the series 'xs in two parts,
'success and 'failure - according to the
outcome of application of the predicate 'p
to all elements of 'xs.
((a -+ logic) -+ [a] -> [[a] [a]]) }
p [any-function!]
xs [series!]
/local us vs result [block!]
][
us: copy []
vs: copy []
foreach k xs [
either p :k [
insert/only tail us :k
][
insert/only tail vs :k
]
]
result: copy []
append/only result us
append/only result vs
result
]
>> partition func [a] [even? a] lst
== [[6 2] [1 5 5 5 1 3]]
这是一个惯用的尝试:
partition-unique: func [
s [block!]
/local got more
][
collect [
parse sort copy s [
any [
copy got [
set more skip
any more
] (keep/only got)
]
]
]
]
partition-by: func [
s [block!]
f [any-function!]
/local result
][
result: reduce [make block! 0 make block! 0]
forall s [append pick result f s/1 s/1]
result
]
用法示例:
>> lst: [1 5 6 5 5 2 1 3]
== [1 5 6 5 5 2 1 3]
>> partition-unique lst
== [[1 1] [2] [3] [5 5 5] [6]]
>> partition-by lst :even?
== [[6 2] [1 5 5 5 1 3]]
将这些组合成一个函数很容易。这里有一些东西可以给你一些基本的想法:
partition: func [
s [block!]
/by f [any-function!]
][
either by [partition-by s :f] [partition-unique s]
]
如何在 Rebol 2 中对列表进行分区?我不关心分区的最终顺序。
例如我想象会有这样的功能:
lst: [1 5 6 5 5 2 1 3]
probe partition lst ; Assuming identity function by default
[[1 1] [5 5 5] [6] [2] [3]]
probe partition/by lst even?
[[6 2] [1 5 5 5 1 3]]
如果没有这样的内置函数,在 Rebol 中构造它的惯用方法是什么?
rebol.org/scripts/hof 上有一些 HOF, 例如实现你第二个愿望的配分函数
partition: func [
{Partition the series 'xs in two parts,
'success and 'failure - according to the
outcome of application of the predicate 'p
to all elements of 'xs.
((a -+ logic) -+ [a] -> [[a] [a]]) }
p [any-function!]
xs [series!]
/local us vs result [block!]
][
us: copy []
vs: copy []
foreach k xs [
either p :k [
insert/only tail us :k
][
insert/only tail vs :k
]
]
result: copy []
append/only result us
append/only result vs
result
]
>> partition func [a] [even? a] lst
== [[6 2] [1 5 5 5 1 3]]
这是一个惯用的尝试:
partition-unique: func [
s [block!]
/local got more
][
collect [
parse sort copy s [
any [
copy got [
set more skip
any more
] (keep/only got)
]
]
]
]
partition-by: func [
s [block!]
f [any-function!]
/local result
][
result: reduce [make block! 0 make block! 0]
forall s [append pick result f s/1 s/1]
result
]
用法示例:
>> lst: [1 5 6 5 5 2 1 3]
== [1 5 6 5 5 2 1 3]
>> partition-unique lst
== [[1 1] [2] [3] [5 5 5] [6]]
>> partition-by lst :even?
== [[6 2] [1 5 5 5 1 3]]
将这些组合成一个函数很容易。这里有一些东西可以给你一些基本的想法:
partition: func [
s [block!]
/by f [any-function!]
][
either by [partition-by s :f] [partition-unique s]
]