arachnea
Version:
A simple api to perform array operations in a single loop
128 lines (127 loc) • 3.88 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ActionType;
(function (ActionType) {
ActionType[ActionType["MAP"] = 0] = "MAP";
ActionType[ActionType["FILTER"] = 1] = "FILTER";
ActionType[ActionType["REMOVE"] = 2] = "REMOVE";
ActionType[ActionType["FOREACH"] = 3] = "FOREACH";
ActionType[ActionType["REDUCE"] = 4] = "REDUCE";
ActionType[ActionType["FIND"] = 5] = "FIND";
ActionType[ActionType["COLLECT"] = 6] = "COLLECT";
})(ActionType || (ActionType = {}));
const conditionToArrayTransformer = (condition) => {
if (typeof condition === 'function') {
return condition;
}
return (ele) => ele === condition;
};
class Stream {
constructor(list) {
this.list = list;
this.actionStack = [];
}
map(transformer) {
this.actionStack.push({
type: ActionType.MAP,
transformer: transformer
});
return this;
}
forEach(transformer) {
this.actionStack.push({
type: ActionType.FOREACH,
transformer: transformer,
});
return this;
}
filter(transformer) {
this.actionStack.push({
type: ActionType.FILTER,
transformer: transformer,
});
return this;
}
remove(condition) {
const transformer = conditionToArrayTransformer(condition);
this.actionStack.push({
type: ActionType.REMOVE,
transformer,
});
return this;
}
actionLoop(operation, interupt = { interrupted: false }) {
let index = 0;
let exclude = false;
while (index < this.list.length) {
if (interupt.interrupted) {
break;
}
let ele = this.list[index];
exclude = false;
for (let i = 0; i < this.actionStack.length; i++) {
if (!this.actionStack[i]) {
continue;
}
const action = this.actionStack[i];
switch (action.type) {
case ActionType.MAP:
ele = action.transformer(ele);
break;
case ActionType.FOREACH:
action.transformer(ele);
break;
case ActionType.FILTER:
exclude = !action.transformer(ele);
break;
case ActionType.REMOVE:
exclude = action.transformer(ele);
if (exclude) {
this.actionStack[i] = null;
}
break;
}
if (exclude) {
break;
}
}
if (!exclude) {
operation(ele);
}
index++;
}
}
reduce(transformer, initialValue) {
if (this.actionStack.length === 0) {
return this.list.reduce(transformer, initialValue);
}
let accumulator = initialValue;
this.actionLoop(ele => {
accumulator = transformer(accumulator, ele);
});
return accumulator;
}
find(condition) {
const condition_ = conditionToArrayTransformer(condition);
let result;
let interrupt = {
interrupted: false,
};
this.actionLoop(ele => {
if (condition_(ele)) {
result = ele;
interrupt.interrupted = true;
}
}, interrupt);
return result;
}
collect() {
let result = [];
this.actionLoop(ele => {
result.push(ele);
});
return result;
}
}
const stream = (arr) => new Stream(arr);
exports.default = stream;