sequences.extras: adding subseq* and safe-subseq.

db4
John Benediktsson 2013-05-24 11:19:27 -07:00
parent 61c6b37e5e
commit 84b5e3828f
3 changed files with 43 additions and 0 deletions

View File

@ -0,0 +1,28 @@
USING: arrays help.markup help.syntax math
sequences.private vectors strings kernel math.order layouts
quotations generic.single ;
IN: sequences.extras
HELP: subseq*
{ $values
{ "from" "an integer" } { "to" "an integer" } { "seq" "sequence" } { "subseq" "sequence" } }
{ $description "Outputs a new sequence using positions relative to one or both ends of the sequence. Positive values describes offsets relative to the start of the sequence, negative values relative to the end. Values of zero for " { $snippet "from" } " indicate the beginning of the sequence, while a zero for " { $snippet "to" } " indicates the end of the sequence." }
{ $notes "Both " { $snippet "from" } " and " { $snippet "to" } " can be safely set to values outside the length of the sequence. Also, " { $snippet "from" } " can safely reference a smaller or greater index position than " { $snippet "to" } "." }
{ $examples
"Using a negative relative index:"
{ $example "USING: prettyprint sequences.extras ; 2 -1 \"abcdefg\" subseq* ."
"\"cdef\""
}
"Using optional indices:"
{ $example "USING: prettyprint sequences.extras ; f -4 \"abcdefg\" subseq* ."
"\"abc\""
}
"Using larger-than-necessary indices:"
{ $example "USING: prettyprint sequences.extras ; 0 10 \"abcdefg\" subseq* ."
"\"abcdefg\""
}
"Trimming from either end of the sequence."
{ $example "USING: prettyprint sequences.extras ; 1 -1 \"abcdefg\" subseq* ."
"\"bcdef\""
}
} ;

View File

@ -156,3 +156,9 @@ IN: sequences.extras.tests
{ t 3 3 } [ 10 iota [ [ odd? ] [ 1 > ] bi* and ] map-find-index ] unit-test
{ f f f } [ 10 iota [ [ odd? ] [ 9 > ] bi* and ] map-find-index ] unit-test
{ "abcdef" } [ f f "abcdef" subseq* ] unit-test
{ "abcdef" } [ 0 f "abcdef" subseq* ] unit-test
{ "ab" } [ f 2 "abcdef" subseq* ] unit-test
{ "cdef" } [ 2 f "abcdef" subseq* ] unit-test
{ "cd" } [ -4 -2 "abcdef" subseq* ] unit-test

View File

@ -32,6 +32,15 @@ IN: sequences.extras
: reduce-from ( ... seq identity quot: ( ... prev elt -- ... next ) i -- ... result )
[ swap ] 2dip each-from ; inline
:: subseq* ( from to seq -- subseq )
seq length :> len
from [ dup 0 < [ len + ] when ] [ 0 ] if*
to [ dup 0 < [ len + ] when ] [ len ] if*
[ 0 len clamp ] bi@ dupd max seq subseq ;
: safe-subseq ( from to seq -- subseq )
[ length '[ 0 _ clamp ] bi@ ] keep subseq ;
: all-subseqs ( seq -- seqs )
dup length [1,b] [ clump ] with map concat ;