Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@westc
Last active March 23, 2023 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westc/e94613b89b44be68770802d0167d36cb to your computer and use it in GitHub Desktop.
Save westc/e94613b89b44be68770802d0167d36cb to your computer and use it in GitHub Desktop.
slice() - A generator function that allows you to get a slice of the values within the given array-like object.
/**
* Generator function allowing you to get a slice of the values within the given
* array-like object.
* @template T
* @param {T[]} list
* The array or array-like object that will be iterated over.
* @param {Object} options
* Optional. The options to change the order of the returned values.
* @param {number=} options.start
* The starting index within `list`. If this is a negative value the starting
* index will be calculated starting from the end of `list`.
* @param {number=} options.stop
* The stopping index within `list`. If this is a negative value the starting
* index will be calculated stopping from the end of `list`.
* @param {number=} options.step
* The amount by which to increment the index between each value to be
* returned within `list`. If this is a negative value the values will be
* returned in reverse order.
* @return {Generator<{value: T, index: number, list: T[]}>}
* @example
* // Get all divs in order.
* for (const {index, value} of slice(document.querySelectorAll('div'))) {
* console.log(index, value);
* }
* @example
* // Get all divs in reverse order.
* const iter = slice(document.querySelectorAll('div'), {step: -1});
* for (const {index, value} of iter) {
* console.log(index, value);
* }
*/
function* slice(list, options) {
let {start, stop, step} = Object(options);
// Make a shallow copy of list as an array.
const array = Array.from(list);
// Ensuring that step, start and stop are correctly defined.
step ||= 1;
const increasing = step > 0;
if (increasing) {
if (start == null) start = 0;
if (stop == null) stop = -1;
}
else {
if (start == null) start = -1;
if (stop == null) stop = 0;
}
if (start < 0) start = array.length >= -start ? array.length + start : 0;
if (stop < 0) stop = array.length >= -stop ? array.length + stop : 0;
for (let index = start; increasing ? index <= stop : (index >= stop); index += step) {
yield {value: array[index], index, list};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment