factor/library/collections/sequence-combinators.factor

176 lines
4.8 KiB
Factor
Raw Normal View History

2006-05-17 14:55:46 -04:00
! Copyright (C) 2005, 2006 Slava Pestov.
2005-12-31 20:51:58 -05:00
! See http://factorcode.org/license.txt for BSD license.
IN: sequences-internals
2006-01-06 02:04:42 -05:00
USING: arrays generic kernel kernel-internals math sequences
vectors ;
2005-09-07 17:21:11 -04:00
2006-01-06 02:04:42 -05:00
: collect ( n generator -- array | quot: n -- value )
2005-12-28 20:25:17 -05:00
>r [ f <array> ] keep r> swap [
[ rot >r [ swap call ] keep r> set-array-nth ] 3keep
] repeat drop ; inline
: (map) ( quot seq i -- quot seq value )
pick pick >r >r swap nth-unsafe swap call r> r> rot ; inline
: (2each) ( quot seq seq i -- quot seq seq i )
[ 2nth-unsafe rot dup slip ] 3keep ; inline
: (2map) ( quot seq seq i -- quot seq seq value )
pick pick >r >r 2nth-unsafe rot dup slip
swap r> swap r> swap ; inline
: (monotonic) ( quot seq i -- ? )
2005-09-16 22:47:28 -04:00
2dup 1+ swap nth-unsafe >r swap nth-unsafe r> rot call ;
inline
2005-12-28 20:25:17 -05:00
: (interleave) ( n -- array )
2006-01-28 15:49:31 -05:00
dup zero? [
2005-12-28 20:25:17 -05:00
drop { }
] [
t <array> f 0 pick set-nth-unsafe
] if ;
2006-02-01 20:10:08 -05:00
: select ( seq quot quot -- seq )
pick >r >r V{ } clone rot [
-rot [
>r over >r call [ r> r> push ] [ r> r> 2drop ] if
] 2keep
] r> call r> like nip ; inline
2006-01-06 02:04:42 -05:00
IN: sequences
2006-05-17 14:55:46 -04:00
: each ( seq quot -- | quot: elt -- )
2005-09-07 17:21:11 -04:00
swap dup length [
[ swap nth-unsafe swap call ] 3keep
2006-05-17 14:55:46 -04:00
] repeat 2drop ; inline
2005-09-07 17:21:11 -04:00
: each-with ( obj seq quot -- | quot: obj elt -- )
swap [ with ] each 2drop ; inline
: reduce ( seq identity quot -- value | quot: x y -- z )
swapd each ; inline
2006-05-17 14:55:46 -04:00
: map ( seq quot -- seq | quot: elt -- elt )
2005-09-07 17:21:11 -04:00
swap [ dup length [ (map) ] collect ] keep like 2nip ;
2006-05-17 14:55:46 -04:00
inline
2005-09-07 17:21:11 -04:00
: map-with ( obj list quot -- list | quot: obj elt -- elt )
swap [ with rot ] map 2nip ; inline
: accumulate ( list identity quot -- values | quot: x y -- z )
rot [ pick >r swap call r> ] map-with nip ; inline
: change-nth ( seq i quot -- )
pick pick >r >r >r swap nth
r> call r> r> swap set-nth ; inline
: inject ( seq quot -- | quot: elt -- elt )
over length
[ [ swap change-nth ] 3keep ] repeat 2drop ;
2005-09-07 17:21:11 -04:00
inline
: min-length ( seq seq -- n )
[ length ] 2apply min ;
2005-10-23 18:33:40 -04:00
: max-length ( seq seq -- n )
[ length ] 2apply max ;
2005-10-23 18:33:40 -04:00
2005-09-07 17:21:11 -04:00
: 2each ( seq seq quot -- )
-rot 2dup min-length [ (2each) ] repeat 3drop ; inline
2005-09-07 17:21:11 -04:00
: 2reduce ( seq seq identity quot -- value | quot: e x y -- z )
>r -rot r> 2each ; inline
: 2map ( seq seq quot -- seq )
-rot
[ 2dup min-length [ (2map) ] collect ] keep like
>r 3drop r> ; inline
2005-09-07 17:21:11 -04:00
2005-10-01 01:44:49 -04:00
: if-bounds ( i seq quot -- )
>r pick pick bounds-check? r> [ 3drop -1 f ] if ; inline
2005-09-07 17:21:11 -04:00
: find* ( i seq quot -- i elt )
2005-10-01 01:44:49 -04:00
[
3dup >r >r >r >r nth-unsafe r> call [
r> dup r> nth-unsafe r> drop
2005-09-07 17:21:11 -04:00
] [
2005-09-16 22:47:28 -04:00
r> 1+ r> r> find*
2005-09-24 15:21:17 -04:00
] if
2005-10-01 01:44:49 -04:00
] if-bounds ; inline
2005-09-07 17:21:11 -04:00
: find-with* ( obj i seq quot -- i elt | quot: elt -- ? )
-rot [ with rot ] find* 2swap 2drop ; inline
2006-05-17 14:55:46 -04:00
: find ( seq quot -- i elt | quot: elt -- ? )
0 -rot find* ; inline
: find-with ( obj seq quot -- i elt | quot: elt -- ? )
swap [ with rot ] find 2swap 2drop ; inline
2005-09-07 17:21:11 -04:00
2005-10-01 01:44:49 -04:00
: find-last* ( i seq quot -- i elt )
[
3dup >r >r >r >r nth-unsafe r> call [
r> dup r> nth-unsafe r> drop
] [
r> 1- r> r> find-last*
] if
] if-bounds ; inline
: find-last-with* ( obj i seq quot -- i elt | quot: elt -- ? )
-rot [ with rot ] find-last* 2swap 2drop ; inline
: find-last ( seq quot -- i elt )
>r [ length 1- ] keep r> find-last* ; inline
: find-last-with ( obj seq quot -- i elt | quot: elt -- ? )
swap [ with rot ] find-last 2swap 2drop ; inline
2005-09-07 17:21:11 -04:00
: contains? ( seq quot -- ? )
find drop -1 > ; inline
: contains-with? ( obj seq quot -- ? )
find-with drop -1 > ; inline
: all? ( seq quot -- ? )
swap [ swap call not ] contains-with? not ; inline
: all-with? ( obj seq quot -- ? | quot: elt -- ? )
swap [ with rot ] all? 2nip ; inline
: subset ( seq quot -- seq | quot: elt -- ? )
2006-02-01 20:10:08 -05:00
[ each ] select ; inline
2005-09-07 17:21:11 -04:00
: subset-with ( obj seq quot -- seq | quot: obj elt -- ? )
swap [ with rot ] subset 2nip ; inline
: monotonic? ( seq quot -- ? | quot: elt elt -- ? )
2005-09-16 22:47:28 -04:00
swap dup length 1- [
2005-09-07 17:21:11 -04:00
pick pick >r >r (monotonic) r> r> rot
] all? 2nip ; inline
2005-10-14 04:05:02 -04:00
2005-12-28 20:25:17 -05:00
: interleave ( seq quot between -- )
rot dup length (interleave) [
[ -rot [ -rot 2slip call ] 2keep ]
[ -rot [ drop call ] 2keep ]
if
] 2each 2drop ; inline
2005-10-14 04:05:02 -04:00
: cache-nth ( i seq quot -- elt | quot: i -- elt )
pick pick ?nth dup [
>r 3drop r>
] [
drop swap >r over >r call dup r> r> set-nth
] if ; inline
: copy-into-check ( start to from -- start to from )
pick over length + pick 2dup length >
[ set-length ] [ 2drop ] if ;
: copy-into ( start to from -- )
copy-into-check dup length
[ >r pick r> + pick set-nth-unsafe ] 2each 2drop ;
inline
: >sequence ( seq quot -- newseq )
over >r >r length r> call dup 0 swap r> copy-into ; inline