203 lines
4.7 KiB
JavaScript
203 lines
4.7 KiB
JavaScript
|
var $break = new Object();
|
||
|
var $continue = new Object();
|
||
|
|
||
|
var Enumerable = {
|
||
|
each: function(iterator) {
|
||
|
var index = 0;
|
||
|
try {
|
||
|
this._each(function(value) {
|
||
|
try {
|
||
|
iterator(value, index++);
|
||
|
} catch (e) {
|
||
|
if (e != $continue) throw e;
|
||
|
}
|
||
|
});
|
||
|
} catch (e) {
|
||
|
if (e != $break) throw e;
|
||
|
}
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
eachSlice: function(number, iterator) {
|
||
|
var index = -number, slices = [], array = this.toArray();
|
||
|
while ((index += number) < array.length)
|
||
|
slices.push(array.slice(index, index+number));
|
||
|
return slices.map(iterator);
|
||
|
},
|
||
|
|
||
|
all: function(iterator) {
|
||
|
var result = true;
|
||
|
this.each(function(value, index) {
|
||
|
result = result && !!(iterator || Prototype.K)(value, index);
|
||
|
if (!result) throw $break;
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
any: function(iterator) {
|
||
|
var result = false;
|
||
|
this.each(function(value, index) {
|
||
|
if (result = !!(iterator || Prototype.K)(value, index))
|
||
|
throw $break;
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
collect: function(iterator) {
|
||
|
var results = [];
|
||
|
this.each(function(value, index) {
|
||
|
results.push((iterator || Prototype.K)(value, index));
|
||
|
});
|
||
|
return results;
|
||
|
},
|
||
|
|
||
|
detect: function(iterator) {
|
||
|
var result;
|
||
|
this.each(function(value, index) {
|
||
|
if (iterator(value, index)) {
|
||
|
result = value;
|
||
|
throw $break;
|
||
|
}
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
findAll: function(iterator) {
|
||
|
var results = [];
|
||
|
this.each(function(value, index) {
|
||
|
if (iterator(value, index))
|
||
|
results.push(value);
|
||
|
});
|
||
|
return results;
|
||
|
},
|
||
|
|
||
|
grep: function(pattern, iterator) {
|
||
|
var results = [];
|
||
|
this.each(function(value, index) {
|
||
|
var stringValue = value.toString();
|
||
|
if (stringValue.match(pattern))
|
||
|
results.push((iterator || Prototype.K)(value, index));
|
||
|
})
|
||
|
return results;
|
||
|
},
|
||
|
|
||
|
include: function(object) {
|
||
|
var found = false;
|
||
|
this.each(function(value) {
|
||
|
if (value == object) {
|
||
|
found = true;
|
||
|
throw $break;
|
||
|
}
|
||
|
});
|
||
|
return found;
|
||
|
},
|
||
|
|
||
|
inGroupsOf: function(number, fillWith) {
|
||
|
fillWith = fillWith === undefined ? null : fillWith;
|
||
|
return this.eachSlice(number, function(slice) {
|
||
|
while(slice.length < number) slice.push(fillWith);
|
||
|
return slice;
|
||
|
});
|
||
|
},
|
||
|
|
||
|
inject: function(memo, iterator) {
|
||
|
this.each(function(value, index) {
|
||
|
memo = iterator(memo, value, index);
|
||
|
});
|
||
|
return memo;
|
||
|
},
|
||
|
|
||
|
invoke: function(method) {
|
||
|
var args = $A(arguments).slice(1);
|
||
|
return this.map(function(value) {
|
||
|
return value[method].apply(value, args);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
max: function(iterator) {
|
||
|
var result;
|
||
|
this.each(function(value, index) {
|
||
|
value = (iterator || Prototype.K)(value, index);
|
||
|
if (result == undefined || value >= result)
|
||
|
result = value;
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
min: function(iterator) {
|
||
|
var result;
|
||
|
this.each(function(value, index) {
|
||
|
value = (iterator || Prototype.K)(value, index);
|
||
|
if (result == undefined || value < result)
|
||
|
result = value;
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
partition: function(iterator) {
|
||
|
var trues = [], falses = [];
|
||
|
this.each(function(value, index) {
|
||
|
((iterator || Prototype.K)(value, index) ?
|
||
|
trues : falses).push(value);
|
||
|
});
|
||
|
return [trues, falses];
|
||
|
},
|
||
|
|
||
|
pluck: function(property) {
|
||
|
var results = [];
|
||
|
this.each(function(value, index) {
|
||
|
results.push(value[property]);
|
||
|
});
|
||
|
return results;
|
||
|
},
|
||
|
|
||
|
reject: function(iterator) {
|
||
|
var results = [];
|
||
|
this.each(function(value, index) {
|
||
|
if (!iterator(value, index))
|
||
|
results.push(value);
|
||
|
});
|
||
|
return results;
|
||
|
},
|
||
|
|
||
|
sortBy: function(iterator) {
|
||
|
return this.map(function(value, index) {
|
||
|
return {value: value, criteria: iterator(value, index)};
|
||
|
}).sort(function(left, right) {
|
||
|
var a = left.criteria, b = right.criteria;
|
||
|
return a < b ? -1 : a > b ? 1 : 0;
|
||
|
}).pluck('value');
|
||
|
},
|
||
|
|
||
|
toArray: function() {
|
||
|
return this.map();
|
||
|
},
|
||
|
|
||
|
zip: function() {
|
||
|
var iterator = Prototype.K, args = $A(arguments);
|
||
|
if (typeof args.last() == 'function')
|
||
|
iterator = args.pop();
|
||
|
|
||
|
var collections = [this].concat(args).map($A);
|
||
|
return this.map(function(value, index) {
|
||
|
return iterator(collections.pluck(index));
|
||
|
});
|
||
|
},
|
||
|
|
||
|
size: function() {
|
||
|
return this.toArray().length;
|
||
|
},
|
||
|
|
||
|
inspect: function() {
|
||
|
return '#<Enumerable:' + this.toArray().inspect() + '>';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Object.extend(Enumerable, {
|
||
|
map: Enumerable.collect,
|
||
|
find: Enumerable.detect,
|
||
|
select: Enumerable.findAll,
|
||
|
member: Enumerable.include,
|
||
|
entries: Enumerable.toArray
|
||
|
});
|