typescript-collections
Version:
A complete, fully tested data structure library written in TypeScript.
418 lines • 16.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Direction;
(function (Direction) {
Direction[Direction["BEFORE"] = 0] = "BEFORE";
Direction[Direction["AFTER"] = 1] = "AFTER";
Direction[Direction["INSIDE_AT_END"] = 2] = "INSIDE_AT_END";
Direction[Direction["INSIDE_AT_START"] = 3] = "INSIDE_AT_START";
})(Direction || (Direction = {}));
var MultiRootTree = /** @class */ (function () {
function MultiRootTree(rootIds, nodes) {
if (rootIds === void 0) { rootIds = []; }
if (nodes === void 0) { nodes = {}; }
this.rootIds = rootIds;
this.nodes = nodes;
this.initRootIds();
this.initNodes();
}
MultiRootTree.prototype.initRootIds = function () {
for (var _i = 0, _a = this.rootIds; _i < _a.length; _i++) {
var rootId = _a[_i];
this.createEmptyNodeIfNotExist(rootId);
}
};
MultiRootTree.prototype.initNodes = function () {
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
for (var _i = 0, _a = this.nodes[nodeKey]; _i < _a.length; _i++) {
var nodeListItem = _a[_i];
this.createEmptyNodeIfNotExist(nodeListItem);
}
}
}
};
MultiRootTree.prototype.createEmptyNodeIfNotExist = function (nodeKey) {
if (!this.nodes[nodeKey]) {
this.nodes[nodeKey] = [];
}
};
MultiRootTree.prototype.getRootIds = function () {
var clone = this.rootIds.slice();
return clone;
};
MultiRootTree.prototype.getNodes = function () {
var clone = {};
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
clone[nodeKey] = this.nodes[nodeKey].slice();
}
}
return clone;
};
MultiRootTree.prototype.getObject = function () {
return {
rootIds: this.getRootIds(),
nodes: this.getNodes(),
};
};
MultiRootTree.prototype.toObject = function () {
return this.getObject();
};
MultiRootTree.prototype.flatten = function () {
var _this = this;
var extraPropsObject = [];
for (var i = 0; i < this.rootIds.length; i++) {
var rootId = this.rootIds[i];
extraPropsObject.push({
id: rootId,
level: 0,
hasParent: false,
childrenCount: 0,
});
traverse(rootId, this.nodes, extraPropsObject, 0);
}
for (var _i = 0, extraPropsObject_1 = extraPropsObject; _i < extraPropsObject_1.length; _i++) {
var o = extraPropsObject_1[_i];
o.childrenCount = countChildren(o.id);
}
return extraPropsObject;
function countChildren(id) {
if (!_this.nodes[id]) {
return 0;
}
else {
var childrenCount = _this.nodes[id].length;
return childrenCount;
}
}
function traverse(startId, nodes, returnArray, level) {
if (level === void 0) { level = 0; }
if (!startId || !nodes || !returnArray || !nodes[startId]) {
return;
}
level++;
var idsList = nodes[startId];
for (var i = 0; i < idsList.length; i++) {
var id = idsList[i];
returnArray.push({ id: id, level: level, hasParent: true });
traverse(id, nodes, returnArray, level);
}
level--;
}
};
MultiRootTree.prototype.moveIdBeforeId = function (moveId, beforeId) {
return this.moveId(moveId, beforeId, Direction.BEFORE);
};
MultiRootTree.prototype.moveIdAfterId = function (moveId, afterId) {
return this.moveId(moveId, afterId, Direction.AFTER);
};
MultiRootTree.prototype.moveIdIntoId = function (moveId, insideId, atStart) {
if (atStart === void 0) { atStart = true; }
if (atStart) {
return this.moveId(moveId, insideId, Direction.INSIDE_AT_START);
}
else {
return this.moveId(moveId, insideId, Direction.INSIDE_AT_END);
}
};
MultiRootTree.prototype.swapRootIdWithRootId = function (rootId, withRootId) {
var leftIndex = this.findRootId(rootId);
var rightIndex = this.findRootId(withRootId);
this.swapRootPositionWithRootPosition(leftIndex, rightIndex);
};
MultiRootTree.prototype.swapRootPositionWithRootPosition = function (swapRootPosition, withRootPosition) {
var temp = this.rootIds[withRootPosition];
this.rootIds[withRootPosition] = this.rootIds[swapRootPosition];
this.rootIds[swapRootPosition] = temp;
};
MultiRootTree.prototype.deleteId = function (id) {
this.rootDeleteId(id);
this.nodeAndSubNodesDelete(id);
this.nodeRefrencesDelete(id);
};
MultiRootTree.prototype.insertIdBeforeId = function (beforeId, insertId) {
var foundRootIdIndex = this.findRootId(beforeId);
if (foundRootIdIndex > -1) {
this.insertIdIntoRoot(insertId, foundRootIdIndex);
}
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
var foundNodeIdIndex = this.findNodeId(nodeKey, beforeId);
if (foundNodeIdIndex > -1) {
this.insertIdIntoNode(nodeKey, insertId, foundNodeIdIndex);
}
}
}
};
MultiRootTree.prototype.insertIdAfterId = function (belowId, insertId) {
var foundRootIdIndex = this.findRootId(belowId);
if (foundRootIdIndex > -1) {
this.insertIdIntoRoot(insertId, foundRootIdIndex + 1);
}
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
var foundNodeIdIndex = this.findNodeId(nodeKey, belowId);
if (foundNodeIdIndex > -1) {
this.insertIdIntoNode(nodeKey, insertId, foundNodeIdIndex + 1);
}
}
}
};
MultiRootTree.prototype.insertIdIntoId = function (insideId, insertId) {
this.nodeInsertAtEnd(insideId, insertId);
this.nodes[insertId] = [];
};
MultiRootTree.prototype.insertIdIntoRoot = function (id, position) {
if (position === undefined) {
this.rootInsertAtEnd(id);
}
else {
if (position < 0) {
var length_1 = this.rootIds.length;
this.rootIds.splice((position + length_1 + 1), 0, id);
}
else {
this.rootIds.splice(position, 0, id);
}
}
this.nodes[id] = this.nodes[id] || [];
};
MultiRootTree.prototype.insertIdIntoNode = function (nodeKey, id, position) {
this.nodes[nodeKey] = this.nodes[nodeKey] || [];
this.nodes[id] = this.nodes[id] || [];
if (position === undefined) {
this.nodeInsertAtEnd(nodeKey, id);
}
else {
if (position < 0) {
var length_2 = this.nodes[nodeKey].length;
this.nodes[nodeKey].splice((position + length_2 + 1), 0, id);
}
else {
this.nodes[nodeKey].splice(position, 0, id);
}
}
};
MultiRootTree.prototype.moveId = function (moveId, beforeId, direction) {
var sourceId = moveId;
var sourceRootIndex = this.findRootId(sourceId);
var sourceNodeKey;
var sourceNodeIdIndex;
if (this.nodes[beforeId]) {
sourceNodeKey = beforeId;
}
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
sourceNodeIdIndex = this.findNodeId(nodeKey, beforeId);
break;
}
}
// got all
var targetId = beforeId;
var targetRootIndex = this.findRootId(targetId);
var targetNodeKey;
var targetNodeIdIndex;
if (this.nodes[beforeId]) {
targetNodeKey = beforeId;
}
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
targetNodeIdIndex = this.findNodeId(nodeKey, beforeId);
break;
}
}
// got all
if (sourceRootIndex > -1) {
if (targetRootIndex > -1) {
// moving root to root
// console.log(`Moving ROOT to ROOT`);
// console.log(`RootIds:`);
// console.log(this.rootIds);
// console.log(`TargetIndex=${targetRootIndex}, SourceIndex=${sourceRootIndex}`);
// console.log(`TargetId=${targetId}, SourceId=${sourceId}`);
this.rootDelete(sourceRootIndex); // indexes change now
if (targetRootIndex > sourceRootIndex) {
targetRootIndex--;
}
else {
}
switch (direction) {
case Direction.BEFORE:
this.insertIdIntoRoot(sourceId, targetRootIndex);
break;
case Direction.AFTER:
this.insertIdIntoRoot(sourceId, targetRootIndex + 1);
break;
case Direction.INSIDE_AT_START:
this.nodeInsertAtStart(targetId, sourceId);
break;
case Direction.INSIDE_AT_END:
this.nodeInsertAtEnd(targetId, sourceId);
break;
}
}
else {
// moving root (source) ABOVE node (target)
// will remove one entry from roots
this.rootDelete(sourceRootIndex);
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
var index = this.findNodeId(nodeKey, targetId);
if (index > -1) {
switch (direction) {
case Direction.BEFORE:
this.insertIdIntoNode(nodeKey, sourceId, index);
break;
case Direction.AFTER:
this.insertIdIntoNode(nodeKey, sourceId, index + 1);
break;
case Direction.INSIDE_AT_START:
this.nodeInsertAtStart(targetId, sourceId);
break;
case Direction.INSIDE_AT_END:
this.nodeInsertAtEnd(targetId, sourceId);
break;
}
break;
}
}
}
}
}
else {
if (targetRootIndex > -1) {
// moving node (source) ABOVE root (target)
// delete source id from each node
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
var index = this.findNodeId(nodeKey, sourceId);
if (index > -1) {
// this.nodeInsertId(nodeKey, sourceId, index);
this.nodeDeleteAtIndex(nodeKey, index);
break;
}
}
}
switch (direction) {
case Direction.BEFORE:
this.insertIdIntoRoot(sourceId, targetRootIndex);
break;
case Direction.AFTER:
this.insertIdIntoRoot(sourceId, targetRootIndex + 1);
break;
case Direction.INSIDE_AT_START:
this.nodeInsertAtStart(targetId, sourceId);
break;
case Direction.INSIDE_AT_END:
this.nodeInsertAtEnd(targetId, sourceId);
break;
}
}
else {
// moving node (source) ABOVE node (target)
// delete source id from each node
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
var index = this.findNodeId(nodeKey, sourceId);
if (index > -1) {
this.nodeDeleteAtIndex(nodeKey, index);
break;
}
}
}
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
var index = this.findNodeId(nodeKey, targetId);
if (index > -1) {
switch (direction) {
case Direction.BEFORE:
this.insertIdIntoNode(nodeKey, sourceId, index);
break;
case Direction.AFTER:
this.insertIdIntoNode(nodeKey, sourceId, index + 1);
break;
case Direction.INSIDE_AT_START:
this.nodeInsertAtStart(targetId, sourceId);
break;
case Direction.INSIDE_AT_END:
this.nodeInsertAtEnd(targetId, sourceId);
break;
}
break;
}
}
}
}
}
};
MultiRootTree.prototype.swapArrayElements = function (arr, indexA, indexB) {
var temp = arr[indexA];
arr[indexA] = arr[indexB];
arr[indexB] = temp;
return arr;
};
MultiRootTree.prototype.rootDeleteId = function (id) {
var index = this.findRootId(id);
if (index > -1) {
this.rootDelete(index);
}
};
MultiRootTree.prototype.nodeAndSubNodesDelete = function (nodeKey) {
var toDeleteLater = [];
for (var i = 0; i < this.nodes[nodeKey].length; i++) {
var id = this.nodes[nodeKey][i];
this.nodeAndSubNodesDelete(id);
toDeleteLater.push(nodeKey);
}
this.nodeDelete(nodeKey);
for (var i = 0; i < toDeleteLater.length; i++) {
this.nodeDelete(toDeleteLater[i]);
}
};
MultiRootTree.prototype.nodeRefrencesDelete = function (id) {
for (var nodeKey in this.nodes) {
if (this.nodes.hasOwnProperty(nodeKey)) {
for (var i = 0; i < this.nodes[nodeKey].length; i++) {
var targetId = this.nodes[nodeKey][i];
if (targetId === id) {
this.nodeDeleteAtIndex(nodeKey, i);
}
}
}
}
};
MultiRootTree.prototype.nodeDelete = function (nodeKey) {
delete this.nodes[nodeKey];
};
MultiRootTree.prototype.findRootId = function (id) {
return this.rootIds.indexOf(id);
};
MultiRootTree.prototype.findNodeId = function (nodeKey, id) {
return this.nodes[nodeKey].indexOf(id);
};
MultiRootTree.prototype.findNode = function (nodeKey) {
return this.nodes[nodeKey];
};
MultiRootTree.prototype.nodeInsertAtStart = function (nodeKey, id) {
this.nodes[nodeKey].unshift(id);
};
MultiRootTree.prototype.nodeInsertAtEnd = function (nodeKey, id) {
this.nodes[nodeKey].push(id);
};
MultiRootTree.prototype.rootDelete = function (index) {
this.rootIds.splice(index, 1);
};
MultiRootTree.prototype.nodeDeleteAtIndex = function (nodeKey, index) {
this.nodes[nodeKey].splice(index, 1);
};
MultiRootTree.prototype.rootInsertAtStart = function (id) {
this.rootIds.unshift(id);
};
MultiRootTree.prototype.rootInsertAtEnd = function (id) {
this.rootIds.push(id);
};
return MultiRootTree;
}());
exports.default = MultiRootTree;
//# sourceMappingURL=MultiRootTree.js.map