Skip to content

Instantly share code, notes, and snippets.

@vmi
Created January 19, 2012 06:54
Show Gist options
  • Save vmi/1638496 to your computer and use it in GitHub Desktop.
Save vmi/1638496 to your computer and use it in GitHub Desktop.
Repeat function with named item
/*
* Fair License (Fair)
*
* Copyright (c) 2012, IWAMURO Motonori
*
* Usage of the works is permitted provided that this instrument is
* retained with the works, so that any entity that uses the works is
* notified of this instrument.
*
* DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
*/
/*
* Repeat function with named item.
*
* CASE1:
* var rp0 = new Repeater();
* rp0.add(NAME1, ITEM1, ..., NAMEn, ITEMn);
* rp0.each(function(i, name, item) {...});
* or
* // bound this in function
* rp0.each(this, function(i, name, item) {...});
*
* rp0.length is added data count.
*
* CASE2:
* var rp0 = new Repeater();
* var rp1 = new Repeater();
* rp0.add(NAME01, ITEM01, ..., NAME0n, ITEM0n);
* rp1.add(NAME11, ITEM11, ..., NAME1m, ITEM1m);
* rp0.each(rp1, function(i0, name0, item0, i1, name1, item1) {...});
* or
* // bound this in function
* rp0.each(rp1, this, function(i0, name0, item0, i1, name1, item1) {...});
*
* rp0.each(rp1, ...) same as:
* for (var i0 = 0; i0 < rp0.length; i0++) {
* var name0 = rp0.data[i0].name; // * pseudo code
* var item0 = rp0.data[i0].item; // * pseudo code
* for (var i1 = 0; i1 < rp1.length; i1++) {
* var name1 = rp1.data[i1].name; // * pseudo code
* var item1 = rp1.data[i1].item; // * pseudo code
* ...
* }
* }
*
* CASEn:
* var rp0 = new Repeater();
* ...
* var rpN = new Repeater();
* ...
* rp0.each(rp1, ..., rpN, function(i0, name0, item0, ..., iN, nameN, itemN) {});
* or
* rp0.each(rp1, ..., rpN, this, function(...) {});
*/
var Repeater = (function() {
// constructor
function Repeater() {
this.data = [];
this.length = 0;
}
// public methods
Repeater.prototype = {
// add items.
add: function(/* NAME1, ITEM1, ..., NAMEn, ITEMn */) {
var len = arguments.length;
if (len % 2 == 1 || len == 0)
throw "arguments length is odd or 0. It is required even and 2 or more.";
var offset = this.data.length;
for (var i = 0; i < len; i += 2) {
var name = arguments[i];
var item = arguments[i + 1];
this.data.push([offset + i, name, item]);
}
this.length = this.data.length;
return this;
},
// call function with each item as parameters.
each: function(/* [RP1, ..., RPn,] [SELF,] FUNC */) {
var len = arguments.length;
var func = arguments[--len];
var self;
if (arguments[len - 1] instanceof Repeater)
self = null;
else
self = arguments[--len];
if (len == 0) {
for (var i = 0; i < this.length; i++)
func.apply(self, this.data[i]);
} else {
_nestedEach.call(this, [],
Array.prototype.slice.call(arguments, 0, len),
self, func);
}
}
};
// private methods
// call function with each items of each Repeater as parameters.
function _nestedEach(args, rps, self, func) {
var i;
if (rps.length == 0) {
for (i = 0; i < this.length; i++)
func.apply(self, args.concat(this.data[i]));
} else {
var rp = rps.shift();
for (i = 0; i < this.length; i++)
_nestedEach.call(rp, args.concat(this.data[i]), rps, self, func);
}
}
return Repeater;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment