44 * JSNetworkX is distributed with the BSD license
55 */
66
7+ function isObjectLike ( value ) {
8+ return ! ! value && typeof value == 'object' ;
9+ }
10+
11+ function isBoolean ( value ) {
12+ var boolTag = '[object Boolean]' ;
13+ return value === true || value === false || ( isObjectLike ( value ) && Object . prototype . toString . call ( value ) == boolTag ) ;
14+ }
15+
16+ function nodesAreEqual ( a , b ) {
17+ return a === b || typeof a === 'object' && a . toString ( ) === b . toString ( ) ;
18+ }
19+
720export function hasPath ( G , { source, target} ) {
821 try {
922 shortestPath ( G , { source, target} ) ;
@@ -94,11 +107,7 @@ function bidirectionalPredSucc(G, source, target) {
94107 }
95108 }
96109 }
97- throw new JSNetworkXNoPath ( sprintf (
98- 'No path between `%j` and `%j`.' ,
99- source ,
100- target
101- ) ) ;
110+ throw new JSNetworkXNoPath ( 'No path between ' + source + ' and ' + target + "." ) ;
102111}
103112
104113function topologicalSort ( G , optNbunch ) {
@@ -112,7 +121,7 @@ function topologicalSort(G, optNbunch) {
112121 optNbunch = G . nodesIter ( ) ;
113122 }
114123
115- optNbunch . forEach ( function ( v ) { // process all vertices in G
124+ for ( let v of optNbunch ) { // process all vertices in G
116125 if ( explored . has ( v ) ) {
117126 return ; // continue
118127 }
@@ -145,7 +154,7 @@ function topologicalSort(G, optNbunch) {
145154 orderExplored . unshift ( w ) ;
146155 }
147156 }
148- } ) ;
157+ }
149158
150159 return orderExplored ;
151160}
@@ -221,6 +230,77 @@ export class DiGraph {
221230 return this . node . keys ( ) ;
222231 }
223232
233+ get ( n ) {
234+ var value = this . adj . get ( n ) ;
235+ if ( typeof value === 'undefined' ) {
236+ throw new KeyError ( 'Graph does not contain node ' + n + '.' ) ;
237+ }
238+ return value ;
239+ }
240+
241+ numberOfNodes ( ) {
242+ return this . node . size ;
243+ }
244+
245+ * nbunchIter ( optNbunch ) {
246+ if ( optNbunch == null ) { // include all nodes
247+ /*jshint expr:true*/
248+ yield * this . adj . keys ( ) ;
249+ }
250+ else if ( this . hasNode ( optNbunch ) ) { // if nbunch is a single node
251+ yield optNbunch ;
252+ }
253+ else { // if nbunch is a sequence of nodes
254+ var adj = this . adj ;
255+
256+ try {
257+ for ( var n of toIterator ( optNbunch ) ) {
258+ if ( adj . has ( n ) ) {
259+ yield n ;
260+ }
261+ }
262+ }
263+ catch ( ex ) {
264+ if ( ex instanceof TypeError ) {
265+ throw new JSNetworkXError (
266+ 'nbunch is not a node or a sequence of nodes'
267+ ) ;
268+ }
269+ }
270+ }
271+ }
272+
273+ * edgesIter ( optNbunch , optData = false ) {
274+ // handle calls with opt_data being the only argument
275+ if ( isBoolean ( optNbunch ) ) {
276+ optData = optNbunch ;
277+ optNbunch = undefined ;
278+ }
279+
280+ var nodesNbrs ;
281+
282+ if ( optNbunch === undefined ) {
283+ nodesNbrs = this . adj ;
284+ }
285+ else {
286+ nodesNbrs = mapIterator (
287+ this . nbunchIter ( optNbunch ) ,
288+ n => tuple2 ( n , this . adj . get ( n ) )
289+ ) ;
290+ }
291+
292+ for ( var nodeNbrs of nodesNbrs ) {
293+ for ( var nbrData of nodeNbrs [ 1 ] ) {
294+ var result = [ nodeNbrs [ 0 ] , nbrData [ 0 ] ] ;
295+ if ( optData ) {
296+ result [ 2 ] = nbrData [ 1 ] ;
297+ }
298+ yield result ;
299+ }
300+ }
301+ }
302+
303+
224304 reverse ( optCopy = true ) {
225305 var H ;
226306 if ( optCopy ) {
0 commit comments