iter-tools-es
Version:
The iterable toolbox
86 lines (69 loc) • 1.73 kB
JavaScript
const {
CircularBuffer
} = require('../../internal/circular-buffer.js');
const {
iterableCurry
} = require('../../internal/iterable.js');
const {
makeValidateArgs
} = require('./internal/validate-args.js');
function* __sliceFromStart(source, start = 0, end = Infinity, step = 1) {
let currentPos = 0;
let nextValidPos = start;
const bufferSize = Math.abs(end);
let buffer;
let counter = 0;
if (end < 0) {
buffer = new CircularBuffer(bufferSize);
}
for (let value of source) {
if (buffer) {
value = buffer.push(value);
counter++;
if (counter <= bufferSize) {
continue;
}
}
if (currentPos >= end && end >= 0) {
break;
}
if (nextValidPos === currentPos) {
yield value;
nextValidPos += step;
}
currentPos++;
}
}
exports.__sliceFromStart = __sliceFromStart;
function bufferedSlice(source, start, end, step) {
const bufferSize = Math.abs(start);
const buffer = new CircularBuffer(bufferSize);
let counter = 0;
for (const value of source) {
buffer.push(value);
counter++;
}
let newEnd;
if (isFinite(end) && end > 0) {
newEnd = end - (counter - buffer.size);
if (newEnd < 0) return [];
} else {
newEnd = end;
}
return __sliceFromStart(buffer, 0, newEnd, step);
}
function* __slice(source, start = 0, end = Infinity, step = 1) {
if (start >= 0) {
yield* __sliceFromStart(source, start, end, step);
} else {
yield* bufferedSlice(source, start, end, step);
}
}
exports.__slice = __slice;
const slice = /*#__PURE__*/iterableCurry(__slice, {
validateArgs: /*#__PURE__*/makeValidateArgs('slice'),
growRight: true,
minArgs: 0,
maxArgs: 3
});
exports.slice = slice;