最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jquery range utility for quick iteration (prototype's $R equivalent) - Stack Overflow

programmeradmin3浏览0评论

In prototype the cumbersome for:

for (i=0; i<10; i++) { ... }

can be written as

$R(0, 10).each(function(i){ ... });

Is there an equivalent of range in JQuery ?

In prototype the cumbersome for:

for (i=0; i<10; i++) { ... }

can be written as

$R(0, 10).each(function(i){ ... });

Is there an equivalent of range in JQuery ?

Share Improve this question edited Dec 28, 2011 at 22:29 Rob W 349k87 gold badges807 silver badges682 bronze badges asked May 18, 2010 at 8:50 clyfeclyfe 23.8k8 gold badges88 silver badges110 bronze badges 4
  • 5 Interesting how the "cumbersome" first example is fewer characters than the second example. It will also run faster. – Tim Down Commented May 18, 2010 at 10:15
  • 1 Admittedly, the first example does have the downside of putting the loop variable i in the current scope (or the global scope if there's no var i elsewhere in this scope). – Tim Down Commented May 18, 2010 at 15:57
  • Maybe not in the above example, since it's dealing with numbers specifically which are not indexes, but when iterating over a collection, all those i's in var i = 0; i < x.length; i++) and object access as x[i] are pure hassle when all that's needed is going over each object in a collection and doing something with it (nothing to do with indexes). Collection iteration and manipulation methods such as map, filter, any, all, each, reduce, .. should be part of each language and I am glad the ES5 spec includes these. – Anurag Commented May 19, 2010 at 2:24
  • 1 Is easier for my brain to think in terms of range-iteration instead of condition-loop-increment I guess, anyway, a range thingy is good to have. – clyfe Commented Jun 2, 2010 at 12:11
Add a ment  | 

2 Answers 2

Reset to default 4

See http://code.google./p/jquery-utils/source/browse/trunk/src/jquery.arrayUtils.js?r=452

jQuery does not provide range expansion natively, but it's an easy addition. There are only two parts to it. First the range function should return an array with the each item in the range expanded to an array value. Next add a method to Array to iterate each object passing in a handler function.

Here we define forEach that's part of the ECMA-262 standard for iterating over arrays. See MDC for more details.

if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(fun /*, thisp*/) {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}

Next, we need a function to expand ranges to an array within the jQuery namespace. Taken from the above URL (original source - http://blog.outofhanwell./2006/03/29/javascript-range-function/) :

$.extend({
    // Returns a range object
    // Author: Matthias Miller
    // Site:   http://blog.outofhanwell./2006/03/29/javascript-range-function/
    range:  function() {
        if (!arguments.length) { return []; }
        var min, max, step;
        if (arguments.length == 1) {
            min  = 0;
            max  = arguments[0]-1;
            step = 1;
        }
        else {
            // default step to 1 if it's zero or undefined
            min  = arguments[0];
            max  = arguments[1]-1;
            step = arguments[2] || 1;
        }
        // convert negative steps to positive and reverse min/max
        if (step < 0 && min >= max) {
            step *= -1;
            var tmp = min;
            min = max;
            max = tmp;
            min += ((max-min) % step);
        }
        var a = [];
        for (var i = min; i <= max; i += step) { a.push(i); }
        return a;
    }
});

Alrighty, now we can do:

$.range(2, 10).forEach(function(v) {
    console.log(v); // 2, 3, 4, .., 9
});

Or use it with a custom step value instead of 1

$.range(2, 20, 4).forEach(function(v) {
    console.log(v); // 2, 6, 10, 14, 18
});

I'd prefer a generator to an array - more elegant (imho) and more memory efficient.

function Range(low, high){
  this.low = low;
  this.high = high;
}
Range.prototype.__iterator__ = function(){
  for (var i = this.low; i <= this.high; i++)
    yield i;
};

Then you can simply

var range = new Range(3, 5);
for (var i in range)
  print(i); // prints 3, then 4, then 5 in sequence

From: https://developer.mozilla/en/Core_JavaScript_1.5_Guide/Iterators_and_Generators

发布评论

评论列表(0)

  1. 暂无评论