seq2slice
Convert a subsequence string to a
Sliceobject.
Usage
var seq2slice = require( '@stdlib/slice/seq2slice' );
seq2slice( str, len, strict )
Converts a subsequence string to a Slice object, where len specifies the maximum number of elements allowed in the slice.
var s = seq2slice( ':5', 10, false );
// returns <Slice>
var v = s.start;
// returns 0
v = s.stop;
// returns 5
v = s.step;
// returns 1
A subsequence string has the following format:
<start>:<stop>:<increment>
where
- If an
incrementis not specified, the default increment is1. An increment of zero is not allowed. - The
startindex is inclusive. - The
stopindex is exclusive. - Both
startandstopindices are optional. If not provided,startandstopdefault to index extremes. Which extremes correspond to which index depends on whether theincrementis positive or negative. - Both
startandstopcan be negative; in which case, the corresponding index is resolved by subtracting the respective value from the provided lengthlen. - Both
startandstopcan use theendkeyword (e.g.,end-2::2,end-3:, etc), which supports basic subtraction and division. - The
endkeyword resolves to the provided lengthlen. Thus,:-1is equivalent to:end-1,:-2is equivalent to:end-2, and so on and so forth. The exception is when performing a division operation when theincrementis less than zero; in which case,endis equal tolen-1in order to preserve user expectations whenend/dequals a whole number and slicing from right-to-left. The result from a division operation is rounded down to the nearest integer value.
var s = seq2slice( 'end:2:-1', 10, false );
// returns <Slice>
var v = s.start;
// returns 9
v = s.stop;
// returns 2
v = s.step;
// returns -1
s = seq2slice( 'end-2:2:-1', 10, false );
// returns <Slice>
v = s.start;
// returns 8
v = s.stop;
// returns 2
v = s.step;
// returns -1
s = seq2slice( 'end/2:2:-1', 10, false );
// returns <Slice>
v = s.start;
// returns 4
v = s.stop;
// returns 2
v = s.step;
// returns -1
When strict is true, the function throws an error if a subsequence string resolves to a slice exceeding index bounds.
var s = seq2slice( '10:20', 10, true );
// throws <RangeError>
Notes
- When
lenis zero, the function always returns a Slice object equivalent to0:0:<increment>. - When
strictisfalse, the resolved slice start is clamped to the slice index bounds (i.e.,[0, len)). - When
strictisfalse, the resolved slice end is upper bound clamped tolen(i.e., one greater than the last possible index). - When the increment is negative, the resolved slice end value may be
null, thus indicating that a non-empty slice should include the first index. - The function ensures that results satisfy the convention that
:ncombined withn:is equivalent to:(i.e., selecting all elements). This convention matches Python slice semantics, but diverges from the MATLAB convention where:nandn:overlap by one element. - Unlike MATLAB, but like Python, the subsequence string is upper-bound exclusive. For example, in Python,
0:2corresponds to the sequence{0,1}. In MATLAB,1:3corresponds to{1,2,3}.
Examples
var seq2slice = require( '@stdlib/slice/seq2slice' );
var s = seq2slice( ':', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 5. step: 1.'
s = seq2slice( '2:', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 2. stop: 5. step: 1.'
s = seq2slice( ':3', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 3. step: 1.'
s = seq2slice( '2:4', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 2. stop: 4. step: 1.'
s = seq2slice( '1:4:2', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 1. stop: 4. step: 2.'
s = seq2slice( '2::2', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 2. stop: 5. step: 2.'
s = seq2slice( ':-2', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 3. step: 1.'
s = seq2slice( ':-1:2', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 4. step: 2.'
s = seq2slice( '-4:-1:2', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 1. stop: 4. step: 2.'
s = seq2slice( '-5:-1', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 4. step: 1.'
s = seq2slice( '::-1', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 4. stop: null. step: -1.'
s = seq2slice( ':0:-1', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 4. stop: 0. step: -1.'
s = seq2slice( '3:0:-1', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 3. stop: 0. step: -1.'
s = seq2slice( '-1:-4:-2', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 4. stop: 1. step: -2.'
s = seq2slice( ':end', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 5. step: 1.'
s = seq2slice( ':end-1', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 4. step: 1.'
s = seq2slice( ':end/2', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 0. stop: 2. step: 1.'
s = seq2slice( 'end/2::-1', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 2. stop: null. step: -1.'
s = seq2slice( 'end-2::-1', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 3. stop: null. step: -1.'
s = seq2slice( 'end/2:', 5, false );
console.log( 'start: %s. stop: %s. step: %s.', s.start, s.stop, s.step );
// => 'start: 2. stop: 5. step: 1.'