Skip to content

Instantly share code, notes, and snippets.

@Craphtex
Created November 28, 2019 02:21
Show Gist options
  • Save Craphtex/5d10213da10683d3171101a8f1e089e0 to your computer and use it in GitHub Desktop.
Save Craphtex/5d10213da10683d3171101a8f1e089e0 to your computer and use it in GitHub Desktop.
Converts an array to an array of n-tuples of its elements.
/**
* Converts an array to an array of n-tuples of its elements.
*
* To generate a gap between the n-tuples a stride can be set. The stride is
* offsetting the starting elements in the derived n-tuples.
*
* span = 3 and stride = 2
* [1,2,3,4,5,6,7] -> [[1,2,3], [3,4,5], [5,6,7]]
*
* span = 2 and stride = 3
* [1,2,3,4,5,6,7] -> [[1,2], [4,5]]
*
* The default edge behavior is to start the first n-tuple on the first element
* and end the last n-tuple on the last element, essentially cutting off the
* edges.
*
* span = 3 and stride = 1
* [1,2,3,4] -> [[1,2,3],[2,3,4]]
*
* By setting a padding the edges will be padded, making the first n-tuple end
* on the first element and the last n-tuple start on the last element.
*
* span = 3, stride = 1 and padding = 0
* [1,2,3,4] -> [[0,0,1],[0,1,2],[1,2,3],[2,3,4],[3,4,0],[4,0,0]]
*
* @param {number} span - The span of the n-tuple.
* @param {number} stride - The stride between starting elements of derived n-tuples.
* @param {*} padding - What to pad edges with.
* @returns {Array} Array of n-tuples.
* @throws {TypeError} When the given span or stride is not integer value.
* @throws {RangeError} When the given span is bigger than the number of
* elements in the array, or the given stride is smaller than 1.
*/
Array.prototype.getTuples = function(span = 1, stride = 1, padding = undefined) {
// Ensure span and stride are integer values.
if (!Number.isInteger(span))
throw TypeError(`The given span (${span}) was not an integer value.`)
if (!Number.isInteger(stride))
throw TypeError(`The given stride (${stride}) was not an integer value.`)
// Make sure the span is at least as small as the array itself.
if (span > this.length)
throw RangeError(`The given span (${span}) exceeded the array size (${this.length}).`)
// Make sure the stride is positive.
if (stride < 1)
throw RangeError(`The given stride (${stride}) was smaller than 1.`)
// Shallow clone the array to enable padding.
let copy = this.slice()
// If padding is defined add it to the front and end of the array.
if (padding !== undefined) {
const edgePadding = Array(span-1).fill(padding)
copy = [...edgePadding, ...copy, ...edgePadding]
}
// Initialize the array to be returned.
const tuples = []
// Extract the n-tuples and add to the return array.
for (let i = 0; i <= copy.length-span; i += stride)
tuples.push(copy.slice(i, i + span))
// Return the list of n-tuples.
return tuples
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment