nope/modules/wamo/helpers/getOrder.ts

119 lines
3.0 KiB
TypeScript
Raw Normal View History

2020-12-30 18:58:23 +00:00
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-12-29 17:06:25
* @modify date 2020-12-30 11:34:20
* @desc [description]
*/
import {
IWaMOBaseModuleDescription,
IWaMOConverterModuleDescription,
IWaMOLineDescription
} from "../types/interfaces";
/**
* Helper Function to get the order of elements.
* Returns a dictionary containing information
* of neigbors for each station in the line.
*
* @export
* @param {IWaMOLineDescription} line The Line-Configuration
* @return {*} Dict, using the Stations-ID as key, as Value Object with the next-station-id and prev-station-id is provided
*/
export function getOrder(line: IWaMOLineDescription) {
const ret: {
[index: string]: {
prev: string | false;
next: string | false;
};
} = {};
for (const id in line.elements) {
const element = line.elements[id];
if (ret[id] === undefined) {
ret[id] = {
prev: false,
next: false
};
}
if (element.leftNeighbor) {
if (ret[element.leftNeighbor] === undefined) {
ret[element.leftNeighbor] = {
prev: false,
next: id
};
} else {
ret[element.leftNeighbor].next = id;
}
ret[id].prev = element.leftNeighbor;
}
}
return ret;
}
/**
* Returns the Elements in the Order, as array.
* Throws errors if items arent connected correctly
* or there are multiple starts.
*
* @export
* @param {IWaMOLineDescription} line The Line-Configuration
*/
export function getOrderAsArray(line: IWaMOLineDescription) {
// First, determine the Elements without a left neigbor
const firstElements = Object.getOwnPropertyNames(line.elements)
.filter((key) => !line.elements[key].leftNeighbor)
.map((key) => line.elements[key]);
if (firstElements.length == 1) {
// Extract the most Left item
const firstItem = firstElements[0];
const itemsToCheck = Object.getOwnPropertyNames(line.elements);
let currentItem = firstItem;
const ret: Array<
IWaMOBaseModuleDescription | IWaMOConverterModuleDescription
> = [];
do {
// Add the Element to the Return Item.
ret.push(currentItem);
// Remove the Element for the Items to Check.
itemsToCheck.splice(itemsToCheck.indexOf(currentItem.id), 1);
let found = false;
// Iterate over the Items and determine the next item.
for (const id in line.elements) {
// Get the Item
const item = line.elements[id];
if (item.leftNeighbor == currentItem.id) {
// Mark the Element as Found and assign
// the new current item
found = true;
currentItem = item;
break;
}
}
if (!found) {
// That should not happen
throw Error("Element isnt connected :'" + currentItem.name + "'");
}
} while (itemsToCheck.length > 1);
// Add the Last Element
ret.push(line.elements[itemsToCheck[0]]);
return ret;
} else {
throw Error("Unconnected Elements");
}
}