Created
September 10, 2013 18:57
-
-
Save mzabriskie/6513968 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is very cool!