seq2slice
Convert a subsequence string to a
Slice
object.
Usage
var seq2slice = require( '@stdlib/slice/base/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
increment
is not specified, the default increment is1
. An increment of zero is not allowed. - The
start
index is inclusive. - The
stop
index is exclusive. - Both
start
andstop
indices are optional. If not provided,start
andstop
default to index extremes. Which extremes correspond to which index depends on whether theincrement
is positive or negative. - Both
start
andstop
can be negative; in which case, the corresponding index is resolved by subtracting the respective value from the provided lengthlen
. - Both
start
andstop
can use theend
keyword (e.g.,end-2::2
,end-3:
, etc), which supports basic subtraction and division. - The
end
keyword resolves to the provided lengthlen
. Thus,:-1
is equivalent to:end-1
,:-2
is equivalent to:end-2
, and so on and so forth. The exception is when performing a division operation when theincrement
is less than zero; in which case,end
is equal tolen-1
in order to preserve user expectations whenend/d
equals 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
The function returns an error object if provided an invalid subsequence string.
var s = seq2slice( '1:2:3:4', 10, false );
// returns { 'code': 'ERR_SLICE_INVALID_SUBSEQUENCE' }
When strict
is true
, the function returns an error object if a subsequence string resolves to a slice exceeding index bounds.
var s = seq2slice( '10:20', 10, true );
// returns { 'code': 'ERR_SLICE_OUT_OF_BOUNDS' }
A returned error object may have one of the following error codes:
- ERR_SLICE_INVALID_SUBSEQUENCE: a subsequence string is invalid.
- ERR_SLICE_INVALID_INCREMENT: a subsequence string must have a non-zero increment.
- ERR_SLICE_OUT_OF_BOUNDS: a subsequence string resolves to a slice exceeding index bounds.
Notes
- When
len
is zero, the function always returns a Slice object equivalent to0:0:<increment>
. - When
strict
isfalse
, the resolved slice start is clamped to the slice index bounds (i.e.,[0, len)
). - When
strict
isfalse
, 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
:n
combined withn:
is equivalent to:
(i.e., selecting all elements). This convention matches Python slice semantics, but diverges from the MATLAB convention where:n
andn:
overlap by one element. - Unlike MATLAB, but like Python, the subsequence string is upper-bound exclusive. For example, in Python,
0:2
corresponds to the sequence{0,1}
. In MATLAB,1:3
corresponds to{1,2,3}
.
Examples
var seq2slice = require( '@stdlib/slice/base/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.'