UNPKG

@rimbu/graph

Version:

Immutable Graph data structures for TypeScript

120 lines 5.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.traverseBreadthFirstCustom = traverseBreadthFirstCustom; exports.traverseBreadthFirstHashed = traverseBreadthFirstHashed; exports.traverseBreadthFirstSorted = traverseBreadthFirstSorted; var tslib_1 = require("tslib"); var common_1 = require("@rimbu/common"); var hashed_1 = require("@rimbu/hashed"); var sorted_1 = require("@rimbu/sorted"); var stream_1 = require("@rimbu/stream"); var custom_1 = require("@rimbu/stream/custom"); var GraphBreadthFirstStream = /** @class */ (function (_super) { tslib_1.__extends(GraphBreadthFirstStream, _super); function GraphBreadthFirstStream(node, graph, addVisitedNode) { var _this = _super.call(this) || this; _this.node = node; _this.graph = graph; _this.addVisitedNode = addVisitedNode; return _this; } GraphBreadthFirstStream.prototype[Symbol.iterator] = function () { return new DirectedGraphBreadthFirstIterable(this.node, this.graph, this.addVisitedNode); }; return GraphBreadthFirstStream; }(custom_1.StreamBase)); var DirectedGraphBreadthFirstIterable = /** @class */ (function (_super) { tslib_1.__extends(DirectedGraphBreadthFirstIterable, _super); function DirectedGraphBreadthFirstIterable(node, graph, addVisitedNode) { var _this = _super.call(this) || this; _this.node = node; _this.graph = graph; _this.addVisitedNode = addVisitedNode; _this.nextIterators = []; addVisitedNode(node); var startConnectionStream = _this.graph.getConnectionStreamFrom(_this.node); _this.currentIterator = startConnectionStream[Symbol.iterator](); return _this; } DirectedGraphBreadthFirstIterable.prototype.fastNext = function (otherwise) { var nextConnection; while (undefined !== (nextConnection = this.currentIterator.fastNext())) { var result = nextConnection; var targetNode = result[1]; if (this.addVisitedNode(targetNode)) { var targetConnectionStream = this.graph.getConnectionStreamFrom(targetNode); this.nextIterators.push(targetConnectionStream[Symbol.iterator]()); return result; } } var nextIterator = this.nextIterators.shift(); if (undefined === nextIterator) return (0, common_1.OptLazy)(otherwise); this.currentIterator = nextIterator; return this.fastNext(otherwise); }; return DirectedGraphBreadthFirstIterable; }(custom_1.FastIteratorBase)); /** * Returns a stream of connections that can be reached in the given `graph` * starting at the given `startNode`, and using breadth-first traversal. It can * avoid loops if needed in a custom way by supplying the `addVisitedNode` function. * @param graph - the graph to traverse * @param startNode - the start node within the graph * @param addVisitedNode - a function taking the currenty traversed node, * and returning true if the node has been traversed before, or false otherwise * @example * ```ts * const g = EdgeGraphHashed.of([1, 2], [2, 3], [1, 3], [3, 4]) * const stream = traverseBreadthFirstCustom(g, 1) * console.log(stream.toArray()) * // => [[1, 2], [1, 3], [2, 3], [3, 4]] * ``` */ function traverseBreadthFirstCustom(graph, startNode, addVisitedNode) { if (addVisitedNode === void 0) { addVisitedNode = function () { return true; }; } if (!graph.nonEmpty() || !graph.hasNode(startNode)) return stream_1.Stream.empty(); return new GraphBreadthFirstStream(startNode, graph, addVisitedNode); } /** * Returns a stream of connections that can be reached in the given `graph` * starting at the given `startNode`, and using breadth-first traversal. It avoids * loops by internally placing the visited nodes in a HashSet builder. * @param graph - the graph to traverse * @param startNode - the start node within the graph * @example * ```ts * const g = EdgeGraphHashed.of([1, 2], [2, 3], [1, 3], [3, 4]) * const stream = traverseBreadthFirstHashed(g, 1) * console.log(stream.toArray()) * // => [[1, 2], [1, 3], [2, 3], [3, 4]] * ``` */ function traverseBreadthFirstHashed(graph, startNode) { if (!graph.nonEmpty() || !graph.hasNode(startNode)) return stream_1.Stream.empty(); var visitSet = hashed_1.HashSet.builder(); return new GraphBreadthFirstStream(startNode, graph, visitSet.add); } /** * Returns a stream of connections that can be reached in the given `graph` * starting at the given `startNode`, and using breadth-first traversal. It avoids * loops by internally placing the visited nodes in a SortedSet builder. * @param graph - the graph to traverse * @param startNode - the start node within the graph * @example * ```ts * const g = EdgeGraphHashed.of([1, 2], [2, 3], [1, 3], [3, 4]) * const stream = traverseBreadthFirstSorted(g, 1) * console.log(stream.toArray()) * // => [[1, 2], [1, 3], [2, 3], [3, 4]] * ``` */ function traverseBreadthFirstSorted(graph, startNode) { if (!graph.nonEmpty() || !graph.hasNode(startNode)) return stream_1.Stream.empty(); var visitSet = sorted_1.SortedSet.builder(); return new GraphBreadthFirstStream(startNode, graph, visitSet.add); } //# sourceMappingURL=traverse-breadth-first.cjs.map