Skip to content

Instantly share code, notes, and snippets.

@mzabriskie
Created September 10, 2013 18:57
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 mzabriskie/6513968 to your computer and use it in GitHub Desktop.
Save mzabriskie/6513968 to your computer and use it in GitHub Desktop.
/**
* Creates an array containing a range of values.
*
* <p>
* Examples:
*
* <code>
* // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
* Array.range(1, 10);
*
* // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
* Array.range(0, 100, 10);
*
* // ['a', 'b', 'c']
* Array.range('a', 'c');
*
* // ['c', 'b', 'a']
* Array.range('c', 'a');
*
* // String values are limited to a length of one.
* // If a length greater than one is provided, only the first character is used.
* // ['f', 'e', 'd', 'c', 'b']
* Array.range('foo', 'bar');
*
* // Mixing string and number values results in the string being converted to zero.
* // [0, 1, 2, 3, 4, 5]
* Array.range('a', 5);
* </code>
*
* @param {Number|String} low The starting value for the range.
* @param {Number|String} high The ending value for the range.
* @param {Number} [step] If provided, <code>step</code> will be the increment between values in the range.
* If not provided, <code>step</code> defaults to 1. <code>step</code> will be converted to a positive number.
* @return {Array} Returns an array of values between <code>low</code> and <code>high</code>.
* If <code>low</code> is greater than <code>high</code>, the range will be
* from <code>high</code> to <code>low</code>. The range will include the values
* represented by <code>low</code> and <code>high</code>.
*/
Array.range = function (low, high, step) {
var range = [],
start, end,
charCode = false,
reverse = false;
// If no step was provided default to 1
step = isNaN(parseInt(step, 10)) ? 1 : Math.abs(step);
// If either low or high is a number, then both low and high must be numbers
if (!isNaN(parseInt(low, 10)) && isNaN(parseInt(high, 10))) {
high = 0;
}
else if (!isNaN(parseInt(high, 10)) && isNaN(parseInt(low, 10))) {
low = 0;
}
// If both low and high are numbers then create a numeric range
if (!isNaN(parseInt(low, 10)) && !isNaN(parseInt(high, 10))) {
low = parseInt(low, 10);
high = parseInt(high, 10);
}
// If both low and high are strings then create a character range
else if (typeof low === 'string' && typeof high === 'string') {
low = low.charCodeAt(0);
high = high.charCodeAt(0);
charCode = true;
}
// If low and high range values were able to be parsed, create the range
if (typeof low === 'number' && typeof high === 'number') {
// Range will need to be reversed if low is greater than high
reverse = low > high;
// Calculate the start and end points of the range
start = Math.min(low, high);
end = Math.max(low, high);
// Verify that step is within the bounds of the range
if (end - start > 0 && step > end - start) {
throw new Error('step exceeds the specified range');
}
// Generate the range
for (var i=start; i<=end; i+=step) {
range[range.length] = charCode ? String.fromCharCode(i) : i;
}
// Reverse the range if needed
if (reverse) {
range.reverse();
}
}
// Return the range
return range;
};
@Malforov
Copy link

Malforov commented Jul 2, 2021

This is very cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment