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 中构造它的惯用方式是什么?

4

2 回答 2

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]
]
于 2017-11-14T15:26:49.747 回答
2

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]]
于 2017-11-14T10:47:54.417 回答