diff --git a/README.md b/README.md index 9abc2a5..273b3b9 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,9 @@ var graph = new Graph({ #### `graph.digraph` Indicates if the graph's edges are directed. Should be considered read-only. +#### `graph.vertexExists(v)` +Returns `true` if a vertex with id `v` exists in the graph, and `false` otherwise. + #### `graph.getVertex(v)` Returns vertex `v` in an object of the following format, - `id` - the vertex's id. @@ -74,6 +77,9 @@ Removes vertex with id `v` from the graph, including any incident edges. #### `graph.removeVertices(vertexIdsOrLabel)` Removes a collection of vertices and their incident edges from the graph. If `vertexIdsOrLabel` is an array of vertex ids, those vertices will be removed. If `vertexIdsOrLabel` is a label, all vertices with that label will be removed. +#### `graph.edgeExists(u, v)` +Returns `true` if an edge from `u` to `v` exists in the graph, and `false` otherwise. This method also accepts a single array argument containing the edge-pair (e.g. `[u, v]`). + #### `graph.getEdge(u, v)` Returns the edge from vertex `u` to vertex `v` in an object of the following format, - `pair` - an array of two vertex ids representing the edge-pair. diff --git a/lib/graph.js b/lib/graph.js index ff4ae0b..f797a75 100644 --- a/lib/graph.js +++ b/lib/graph.js @@ -104,6 +104,11 @@ exports = module.exports = internals.Graph = function (definition) { }; +internals.Graph.prototype.vertexExists = function (v) { + + return !!this._vertices[v]; +}; + internals.Graph.prototype.getVertex = function (v) { var vertex = this._vertices[v] || null; @@ -185,6 +190,19 @@ internals.Graph.prototype.removeVertices = function (vertices /* or a label */) return this; }; +internals.Graph.prototype.edgeExists = function (u, v) { + + if (Array.isArray(u)) { + + Hoek.assert(u.length === 2, 'Not a proper edge pair.'); + + v = u[1]; + u = u[0]; + } + + return !!this._lookupEdge(u, v); +}; + internals.Graph.prototype.getEdge = function (u, v) { if (Array.isArray(u)) { diff --git a/lib/traversal.js b/lib/traversal.js index 74f1114..a90081e 100644 --- a/lib/traversal.js +++ b/lib/traversal.js @@ -17,7 +17,7 @@ exports = module.exports = internals.Traversal = function (graph) { internals.Traversal.prototype.hop = function (v) { - Hoek.assert(this.graph.getVertex(v), 'Vertex [', v, '] does not exist.'); + Hoek.assert(this.graph.vertexExists(v), 'Vertex [', v, '] does not exist.'); this._records.push({ act: 'hop', args: [v] }); this._visit(v); @@ -51,7 +51,7 @@ internals.Traversal.prototype.currentVertex = function () { internals.Traversal.prototype.visits = function (v) { - Hoek.assert(this.graph.getVertex(v), 'Vertex [', v, '] does not exist.'); + Hoek.assert(this.graph.vertexExists(v), 'Vertex [', v, '] does not exist.'); return (this._visited[v] || 0); }; diff --git a/test/index.js b/test/index.js index 6031459..a7eb1a8 100644 --- a/test/index.js +++ b/test/index.js @@ -508,6 +508,19 @@ describe('Gert', function () { done(); }); + it('vertexExists(v) indicates whether a vertex exists in a graph.', function (done) { + + var graph = new Graph({ vertices: [1, 'a', 2.2] }); + + expect(graph.vertexExists(1)).to.equal(true); + expect(graph.vertexExists('a')).to.equal(true); + expect(graph.vertexExists(2.2)).to.equal(true); + + expect(graph.vertexExists('non')).to.equal(false); + + done(); + }); + it('getVertex(v) returns empty and non-empty vertex information.', function (done) { var data = { @@ -975,6 +988,42 @@ describe('Gert', function () { done(); }); + it('edgeExists(u, v) and edgeExists([u, v]) indicate whether an edge exists in a graph.', function (done) { + + var digraph = new Graph({ + digraph: true, + edges: [ + ['a', 'b'], + ['b', 'a'], + ['b', 'c'], + ['b', 'b'] + ] + }); + + var nondigraph = new Graph({ + digraph: false, + edges: [ + ['a', 'b'], + ['b', 'b'] + ] + }); + + expect(digraph.edgeExists('a', 'b')).to.equal(true); + expect(digraph.edgeExists('b', 'a')).to.equal(true); + expect(digraph.edgeExists('b', 'c')).to.equal(true); + expect(digraph.edgeExists('b', 'b')).to.equal(true); + expect(digraph.edgeExists('c', 'b')).to.equal(false); + + expect(digraph.edgeExists(['a', 'b'])).to.equal(true); + expect(digraph.edgeExists(['c', 'b'])).to.equal(false); + + expect(nondigraph.edgeExists('a', 'b')).to.equal(true); + expect(nondigraph.edgeExists('b', 'a')).to.equal(true); + expect(nondigraph.edgeExists('b', 'b')).to.equal(true); + + done(); + }); + it('getEdge(u, v) and getEdge([u, v]) returns the specified edge or null if no match.', function (done) { var graph = new Graph({