diff --git a/index.html b/index.html
index c2b1ac241..dd2bcbb0c 100644
--- a/index.html
+++ b/index.html
@@ -107,11 +107,11 @@
@@ -186,7 +186,7 @@ _(lyrics).chain()
first, rest, last,
compact, flatten, without, uniq,
intersect, zip, indexOf,
- lastIndexOf
+ lastIndexOf, range
@@ -583,6 +583,28 @@ _.indexOf([1, 2, 3], 2);
_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
=> 4
+
+
+
+ _.range([start], stop, [step])
+
+ A function to create flexibly-numbered lists of integers, handy for
+ each and map loops. start, if omitted, defaults
+ to 0; step defaults to 1. Returns a list of integers
+ from start to stop, incremented (or decremented) by step,
+ exclusive.
+
+
+_.range(10);
+=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+_.range(1, 11);
+=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+_.range(0, 30, 5);
+=> [0, 5, 10, 15, 20, 25]
+_.range(0, -10, -1);
+=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
+_.range(0);
+=> []
Function (uh, ahem) Functions
@@ -930,6 +952,15 @@ _([1, 2, 3]).value();
Change Log
+
+
+ Added the range function, a port of the
+ Python
+ function of the same name, for generating flexibly-numbered lists
+ of integers. Original patch contributed by
+ Kirill Ishanov.
+
+
Added rest for Arrays and arguments objects, and aliased
diff --git a/test/arrays.js b/test/arrays.js
index 5464756f6..3b0ad20a1 100644
--- a/test/arrays.js
+++ b/test/arrays.js
@@ -86,4 +86,15 @@ $(document).ready(function() {
equals(result, 5, 'works on an arguments object');
});
+ test("arrays: range", function() {
+ equals(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array');
+ equals(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
+ equals(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a b-a, a < b generates an array with a single element, equal to a');
+ equals(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
+ equals(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs');
+ });
+
});
diff --git a/test/generators.js b/test/generators.js
deleted file mode 100644
index ea7982de1..000000000
--- a/test/generators.js
+++ /dev/null
@@ -1,15 +0,0 @@
-$(document).ready(function() {
-
- module("Generator functions (range...)");
-
- test("generators: range", function() {
- equals(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array');
- equals(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
- equals(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a b-a, a < b generates an array with a single element, equal to a');
- equals(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
- });
-});
-
diff --git a/test/speed.js b/test/speed.js
index 8313b1d56..86663a237 100644
--- a/test/speed.js
+++ b/test/speed.js
@@ -63,4 +63,8 @@
return _.intersect(numbers, randomized);
});
+ JSLitmus.test('_.range()', function() {
+ return _.range(1000);
+ });
+
})();
\ No newline at end of file
diff --git a/test/test.html b/test/test.html
index 86b73318e..c174ea0a6 100644
--- a/test/test.html
+++ b/test/test.html
@@ -7,7 +7,6 @@
-
diff --git a/underscore-min.js b/underscore-min.js
index 2fcd2eb12..80bfa08c2 100644
--- a/underscore-min.js
+++ b/underscore-min.js
@@ -1,2 +1,15 @@
-(function(){var j=this;var k=j._;var m=function(a){this._wrapped=a};var o=typeof StopIteration!=='undefined'?StopIteration:'__break__';var _=j._=function(a){return new m(a)};if(typeof exports!=='undefined')exports._=_;_.VERSION='0.4.5';_.range=function(a,b,c){if(!b){var b=a;a=0}if(!c)var c=1;var d=Math.ceil((b-a)/c);if(d<0){return[]}var e=new Array(d);var f=0;for(var i=a;(a<=b?b-i>0:i-b>0);i+=c){e[f++]=i}return e};_.each=function(a,b,c){var d=0;try{if(a.forEach){a.forEach(b,c)}else if(a.length){for(var i=0,l=a.length;i=h.computed&&(h={value:a,computed:d})});return h.value};_.min=function(e,f,g){if(!f&&_.isArray(e))return Math.min.apply(Math,e);var h={computed:Infinity};_.each(e,function(a,b,c){var d=f?f.call(g,a,b,c):a;db?1:0}),'value')};_.sortedIndex=function(a,b,c){c=c||_.identity;var d=0,high=a.length;while(d>1;c(a[e])=0})})};_.zip=function(){var a=_.toArray(arguments);var b=_.max(_.pluck(a,'length'));var c=new Array(b);for(var i=0;i=0;i--){arguments=[a[i].apply(this,arguments)]}return arguments[0]}};_.keys=function(c){return _.map(c,function(a,b){return b})};_.values=function(a){return _.map(a,_.identity)};_.extend=function(a,b){for(var c in b)a[c]=b[c];return a};_.clone=function(a){if(_.isArray(a))return a.slice(0);return _.extend({},a)};_.isEqual=function(a,b){if(a===b)return true;var c=typeof(a),btype=typeof(b);if(c!=btype)return false;if(a==b)return true;if(a.isEqual)return a.isEqual(b);if(_.isNumber(a)&&_.isNumber(b)&&isNaN(a)&&isNaN(b))return true;if(c!=='object')return false;var d=_.keys(a),bKeys=_.keys(b);if(d.length!=bKeys.length)return false;for(var e in a)if(!_.isEqual(a[e],b[e]))return false;return true};_.isEmpty=function(a){return(_.isArray(a)?a:_.values(a)).length==0};_.isElement=function(a){return!!(a&&a.nodeType==1)};_.isArray=function(a){return Object.prototype.toString.call(a)=='[object Array]'};_.isFunction=function(a){return Object.prototype.toString.call(a)=='[object Function]'};_.isString=function(a){return Object.prototype.toString.call(a)=='[object String]'};_.isNumber=function(a){return Object.prototype.toString.call(a)=='[object Number]'};_.isUndefined=function(a){return typeof a=='undefined'};_.noConflict=function(){j._=k;return this};_.identity=function(a){return a};_.breakLoop=function(){throw o;};var p=0;_.uniqueId=function(a){var b=p++;return a?a+b:b};_.functions=function(){var a=[];for(var b in _)if(Object.prototype.hasOwnProperty.call(_,b))a.push(b);return _.without(a,'VERSION','prototype','noConflict').sort()};_.template=function(a,b){var c=new Function('obj','var p=[],print=function(){p.push.apply(p,arguments);};'+'with(obj){p.push(\''+a.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return b?c(b):c};_.forEach=_.each;_.foldl=_.inject=_.reduce;_.foldr=_.reduceRight;_.filter=_.select;_.every=_.all;_.some=_.any;_.head=_.first;_.tail=_.rest;_.methods=_.functions;var q=function(a,b){return b?_(a).chain():a};_.each(_.functions(),function(a){m.prototype[a]=function(){Array.prototype.unshift.call(arguments,this._wrapped);return q(_[a].apply(_,arguments),this._chain)}});_.each(['pop','push','reverse','shift','sort','splice','unshift'],function(a){m.prototype[a]=function(){Array.prototype[a].apply(this._wrapped,arguments);return q(this._wrapped,this._chain)}});_.each(['concat','join','slice'],function(a){m.prototype[a]=function(){return q(Array.prototype[a].apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}})();
-
+(function(){var j=this,m=j._,i=function(a){this._wrapped=a},l=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;b.VERSION="0.4.6";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(a.length)for(var e=0,f=a.length;e=e.computed&&(e={value:f,computed:g})});
+return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;gf?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=
+b.max(b.pluck(a,"length")),d=new Array(c),e=0;e0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(){var a=Array.prototype.pop.call(arguments);b.each(arguments,function(c){a[c]=b.bind(a[c],a)})};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=
+[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=a.length-1;c>=0;c--)arguments=[a[c].apply(this,arguments)];return arguments[0]}};b.keys=function(a){return b.map(a,function(c,d){return d})};b.values=function(a){return b.map(a,b.identity)};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.isEqual=function(a,c){if(a===c)return true;
+var d=typeof a,e=typeof c;if(d!=e)return false;if(a==c)return true;if(a.isEqual)return a.isEqual(c);if(b.isNumber(a)&&b.isNumber(c)&&isNaN(a)&&isNaN(c))return true;if(d!=="object")return false;d=b.keys(a);e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return(b.isArray(a)?a:b.values(a)).length==0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return Object.prototype.toString.call(a)==
+"[object Array]"};b.isFunction=function(a){return Object.prototype.toString.call(a)=="[object Function]"};b.isString=function(a){return Object.prototype.toString.call(a)=="[object String]"};b.isNumber=function(a){return Object.prototype.toString.call(a)=="[object Number]"};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=m;return this};b.identity=function(a){return a};b.breakLoop=function(){throw l;};var n=0;b.uniqueId=function(a){var c=n++;return a?a+c:c};b.functions=
+function(){var a=[];for(var c in b)Object.prototype.hasOwnProperty.call(b,c)&&a.push(c);return b.without(a,"VERSION","prototype","noConflict").sort()};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return c?
+a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var k=function(a,c){return c?b(a).chain():a};b.each(b.functions(),function(a){i.prototype[a]=function(){Array.prototype.unshift.call(arguments,this._wrapped);return k(b[a].apply(b,arguments),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){i.prototype[a]=function(){Array.prototype[a].apply(this._wrapped,
+arguments);return k(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){i.prototype[a]=function(){return k(Array.prototype[a].apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();
diff --git a/underscore.js b/underscore.js
index dacba7c01..57f2659ab 100644
--- a/underscore.js
+++ b/underscore.js
@@ -31,35 +31,7 @@
if (typeof exports !== 'undefined') exports._ = _;
// Current version.
- _.VERSION = '0.4.5';
-
- /*------------------------ Generator Functions: ---------------------------*/
-
- // Generates an Array, containing an arithmetic progressions
- // Analog of python's built-in function 'range'
- _.range = function(start, stop, step) {
- if (!stop) {
- var stop = start;
- start = 0;
- }
-
- if (!step) var step = 1;
-
- var length = Math.ceil((stop - start) / step);
-
- if (length < 0) {
- return [];
- }
-
- var results = new Array(length);
- var resIdx = 0;
-
- for (var i = start; (start <= stop ? stop - i > 0 : i - stop > 0); i += step) {
- results[resIdx++] = i;
- }
-
- return results;
- };
+ _.VERSION = '0.4.6';
/*------------------------ Collection Functions: ---------------------------*/
@@ -343,6 +315,22 @@
return -1;
};
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python range() function. See:
+ // http://docs.python.org/library/functions.html#range
+ _.range = function(start, stop, step) {
+ var a = _.toArray(arguments);
+ var solo = a.length <= 1;
+ var start = solo ? 0 : a[0], stop = solo ? a[0] : a[1], step = a[2] || 1;
+ var len = Math.ceil((stop - start) / step);
+ if (len <= 0) return [];
+ var range = new Array(len);
+ for (var i = start, idx = 0; true; i += step) {
+ if ((step > 0 ? i - stop : stop - i) >= 0) return range;
+ range[idx++] = i;
+ }
+ };
+
/* ----------------------- Function Functions: -----------------------------*/
// Create a function bound to a given object (assigning 'this', and arguments,