import LinkedList from '../linked-list/LinkedList'; export default class GraphVertex { constructor(value) { if (value === undefined) { throw new Error('Graph vertex must have a value'); } // Normally you would store string value like vertex name. // But generally it may be any object as well this.value = value; this.edges = new LinkedList(); } /** * @param {GraphEdge} edge * @returns {GraphVertex} */ addEdge(edge) { this.edges.append(edge); return this; } /** * @returns {GraphVertex[]} */ getNeighbors() { const edges = this.edges.toArray(); const neighborsConverter = ({ value }) => { return value.startVertex === this ? value.endVertex : value.startVertex; }; // Return either start or end vertex. // For undirected graphs it is possible that current vertex will be the end one. return edges.map(neighborsConverter); } /** * @param {GraphEdge} requiredEdge * @returns {boolean} */ hasEdge(requiredEdge) { const edgeNode = this.edges.find({ callback: edge => edge === requiredEdge, }); return !!edgeNode; } /** * @param {GraphVertex} vertex * @returns {boolean} */ hasNeighbor(vertex) { const vertexNode = this.edges.find({ callback: edge => edge.startVertex === vertex || edge.endVertex === vertex, }); return !!vertexNode; } /** * @param {GraphVertex} vertex * @returns {(GraphEdge|null)} */ findEdge(vertex) { const edgeFinder = (edge) => { return edge.startVertex === vertex || edge.endVertex === vertex; }; const edge = this.edges.find({ callback: edgeFinder }); return edge ? edge.value : null; } /** * @returns {string} */ getKey() { return this.value; } /** * @param {function} [callback] * @returns {string} */ toString(callback) { return callback ? callback(this.value) : `${this.value}`; } }