Created
May 24, 2011 01:31
-
-
Save peterhil/988005 to your computer and use it in GitHub Desktop.
A perfect range function
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
// JavaScript Range Function | |
// © 2006 Matthias Miller (originally written March 29, 2006) | |
// © 2010-2011 Peter Hillerström (modified 20.10.2010) | |
// Feel free to use it under the BSD license. | |
// Version: 0.1 Matthias Miller (originally written March 29, 2006) | |
// Version: 0.2 Peter Hillerström (modified October 20, 2010) | |
// Version: 0.3 Peter Hillerström (rewritten on May 24, 2011) | |
// Original found on Matthias’ blog entry: | |
// http://outofhanwell.wordpress.com/2006/03/29/javascript-range-function/ | |
// Sometimes I get hit by random thoughts in the middle of some programming changes. | |
// Have you ever wanted to write code like this? | |
// | |
// for (var i in range(12)) ... | |
// or: | |
// for (var i in range(-10,11,5)) ... | |
function sign(x) { | |
return x/Math.abs(x) || 0; | |
} | |
function range(/*[start,] end[, step]*/) { | |
var a = Array.prototype.slice.call(arguments), | |
start = (a.length === 1) ? 0 : a[0], // when given only one argument: start from 0, | |
end = (a[1] !== undefined) ? a[1] : a[0], // and default end to the first argument | |
step = (a[2] !== undefined) ? a[2] : 1, // default to 1 | |
cur = start, | |
result = []; | |
step = Math.abs(step) * sign(end-start); // Normalize the step direction | |
if (Math.abs(step) > Math.abs(end-start)) { // Step can't be larger than the interval | |
return result; | |
} | |
do { | |
result.push(cur); | |
cur += step; | |
} while (sign(step)*(cur-start) < sign(step)*(end-start)); | |
return (sign(a[2]) === -1) ? result.reverse() : result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage examples:
// Basics
range(12)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
range(3,12)
[3, 4, 5, 6, 7, 8, 9, 10, 11]
range(3,12,4)
[3, 7, 11]
// Limits always work - if step size is negative, reverse the reult
range(-3,12)
[-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
range(3,-12)
[3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11]
range(3,-12,-1)
[-11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3]
range(-3,12,-1)
[11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3]
range(-3,12,3)
[-3, 0, 3, 6, 9]
range(-3,12,-3)
[9, 6, 3, 0, -3]
// Can't take from interval [start,end] with step size larger than the interval.
range(3,15,10)
[3, 13]
range(3,15,11)
[3, 14]
range(3,15,12)
[3]
range(3,15,13)
[]
range(3,15,14)
[]