lodash-contrib
Version:
The brass buckles on lodash's utility belt
325 lines (293 loc) • 6.68 kB
JavaScript
module.exports = function (_) {
// Helpers
// -------
var HASNTBEENRUN = {};
function unary (fun) {
return function (first) {
return fun.call(this, first);
};
}
function binary (fun) {
return function (first, second) {
return fun.call(this, first, second);
};
}
// Mixing in the iterator functions
// --------------------------------
function foldl (iter, binaryFn, seed) {
var state, element;
if (seed !== void 0) {
state = seed;
}
else {
state = iter();
}
element = iter();
while (element != null) {
state = binaryFn.call(element, state, element);
element = iter();
}
return state;
}
function unfold (seed, unaryFn) {
var state = HASNTBEENRUN;
return function () {
if (state === HASNTBEENRUN) {
state = seed;
} else if (state != null) {
state = unaryFn.call(state, state);
}
return state;
};
}
// note that the unfoldWithReturn behaves differently than
// unfold with respect to the first value returned
function unfoldWithReturn (seed, unaryFn) {
var state = seed,
pair,
value;
return function () {
if (state != null) {
pair = unaryFn.call(state, state);
value = pair[1];
state = value != null ? pair[0] : void 0;
return value;
}
else return void 0;
};
}
function accumulate (iter, binaryFn, initial) {
var state = initial;
return function () {
var element = iter();
if (element == null) {
return element;
}
else {
if (state === void 0) {
state = element;
} else {
state = binaryFn.call(element, state, element);
}
return state;
}
};
}
function accumulateWithReturn (iter, binaryFn, initial) {
var state = initial,
stateAndReturnValue,
element;
return function () {
element = iter();
if (element == null) {
return element;
}
else {
if (state === void 0) {
state = element;
return state;
}
else {
stateAndReturnValue = binaryFn.call(element, state, element);
state = stateAndReturnValue[0];
return stateAndReturnValue[1];
}
}
};
}
function map (iter, unaryFn) {
return function() {
var element;
element = iter();
if (element != null) {
return unaryFn.call(element, element);
} else {
return void 0;
}
};
}
function mapcat(iter, unaryFn) {
var lastIter = null;
return function() {
var element;
var gen;
if (lastIter == null) {
gen = iter();
if (gen == null) {
lastIter = null;
return void 0;
}
lastIter = unaryFn.call(gen, gen);
}
while (element == null) {
element = lastIter();
if (element == null) {
gen = iter();
if (gen == null) {
lastIter = null;
return void 0;
}
else {
lastIter = unaryFn.call(gen, gen);
}
}
}
return element;
};
}
function select (iter, unaryPredicateFn) {
return function() {
var element;
element = iter();
while (element != null) {
if (unaryPredicateFn.call(element, element)) {
return element;
}
element = iter();
}
return void 0;
};
}
function reject (iter, unaryPredicateFn) {
return select(iter, function (something) {
return !unaryPredicateFn(something);
});
}
function find (iter, unaryPredicateFn) {
return select(iter, unaryPredicateFn)();
}
function slice (iter, numberToDrop, numberToTake) {
var count = 0;
while (numberToDrop-- > 0) {
iter();
}
if (numberToTake != null) {
return function() {
if (++count <= numberToTake) {
return iter();
} else {
return void 0;
}
};
}
else return iter;
}
function drop (iter, numberToDrop) {
return slice(iter, numberToDrop == null ? 1 : numberToDrop);
}
function take (iter, numberToTake) {
return slice(iter, 0, numberToTake == null ? 1 : numberToTake);
}
function List (array) {
var index = 0;
return function() {
return array[index++];
};
}
function Tree (array) {
var index, myself, state;
index = 0;
state = [];
myself = function() {
var element, tempState;
element = array[index++];
if (element instanceof Array) {
state.push({
array: array,
index: index
});
array = element;
index = 0;
return myself();
} else if (element === void 0) {
if (state.length > 0) {
tempState = state.pop();
array = tempState.array;
index = tempState.index;
return myself();
} else {
return void 0;
}
} else {
return element;
}
};
return myself;
}
function K (value) {
return function () {
return value;
};
}
function upRange (from, to, by) {
return function () {
var was;
if (from > to) {
return void 0;
}
else {
was = from;
from = from + by;
return was;
}
};
}
function downRange (from, to, by) {
return function () {
var was;
if (from < to) {
return void 0;
}
else {
was = from;
from = from - by;
return was;
}
};
}
function range (from, to, by) {
if (from == null) {
return upRange(1, Infinity, 1);
}
else if (to == null) {
return upRange(from, Infinity, 1);
}
else if (by == null) {
if (from <= to) {
return upRange(from, to, 1);
}
else return downRange(from, to, 1);
}
else if (by > 0) {
return upRange(from, to, by);
}
else if (by < 0) {
return downRange(from, to, Math.abs(by));
}
else return k(from);
}
var numbers = unary(range);
_.iterators = {
accumulate: accumulate,
accumulateWithReturn: accumulateWithReturn,
foldl: foldl,
reduce: foldl,
unfold: unfold,
unfoldWithReturn: unfoldWithReturn,
map: map,
mapcat: mapcat,
select: select,
reject: reject,
filter: select,
find: find,
slice: slice,
drop: drop,
take: take,
List: List,
Tree: Tree,
constant: K,
K: K,
numbers: numbers,
range: range
};
};