Skip to content

Commit 2060593

Browse files
committed
feat: allow conditional traversal during depthFirstSearch algorithm
1 parent 037182f commit 2060593

3 files changed

Lines changed: 20 additions & 23 deletions

File tree

src/algorithms/depthFirstSearch/depthFirstSearch.spec.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,21 @@ import { Graph } from '../../Graph.js';
33
import { depthFirstSearch } from './index.js';
44

55
describe('depthFirstSearch', () => {
6-
it.todo(
7-
'Should return the nodes connected to the source node with the correct type of edge.',
8-
function () {
9-
const graph = new Graph<string, { type: 'follow' | 'stop' }>();
6+
it('Should return the nodes connected to the source node with the correct type of edge.', function () {
7+
const graph = new Graph<string, { type: 'foo' | 'bar' }>();
108

11-
// Shoes depend on socks.
12-
// Socks need to be put on before shoes.
13-
graph.addEdge('a', 'b', undefined, { type: 'follow' });
9+
graph.addEdge('a', 'b', undefined, { type: 'foo' });
10+
graph.addEdge('b', 'c', undefined, { type: 'bar' });
11+
graph.addEdge('b', 'd', undefined, { type: 'bar' });
12+
graph.addEdge('b', 'e', undefined, { type: 'foo' });
1413

15-
const nodes = depthFirstSearch(graph, {
16-
visit: (source, target, graph) =>
17-
graph.getEdgeProperties(source, target).type === 'follow',
18-
});
14+
const nodes = depthFirstSearch(graph, {
15+
shouldFollow: (source, target, graph) =>
16+
graph.getEdgeProperties(source, target).type === 'foo',
17+
});
1918

20-
// expect(sorted.length).toEqual(8);
21-
expect(nodes).toContain('socks');
22-
expect(nodes).toContain('shoes');
23-
},
24-
);
19+
expect(nodes).toContain('a');
20+
expect(nodes).toContain('b');
21+
expect(nodes).toContain('e');
22+
});
2523
});

src/algorithms/depthFirstSearch/depthFirstVisit.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CycleError } from '../../CycleError.js';
22
import { Graph } from '../../Graph.js';
3-
import { Edge, NoInfer } from '../../types.js';
3+
import { NoInfer } from '../../types.js';
44
import { DepthFirstSearchOptions } from './types.js';
55

66
export function depthFirstVisit<Node, LinkProps>(
@@ -9,9 +9,9 @@ export function depthFirstVisit<Node, LinkProps>(
99
visited: Set<NoInfer<Node>>,
1010
visiting: Set<NoInfer<Node>>,
1111
node: NoInfer<Node>,
12-
opts: Pick<DepthFirstSearchOptions<Node, LinkProps>, 'errorOnCycle' | 'visit'>,
12+
opts: Pick<DepthFirstSearchOptions<Node, LinkProps>, 'errorOnCycle' | 'shouldFollow'>,
1313
) {
14-
const { errorOnCycle = false, visit } = opts;
14+
const { errorOnCycle = false, shouldFollow } = opts;
1515

1616
if (visiting.has(node) && errorOnCycle) {
1717
throw new CycleError('Cycle found');
@@ -22,9 +22,8 @@ export function depthFirstVisit<Node, LinkProps>(
2222
visiting.add(node);
2323

2424
graph.adjacent(node)?.forEach((n) => {
25-
// TODO
26-
// const shouldVisit = visit === undefined || (visit && visit(node, n, graph));
27-
// if (!shouldVisit) return;
25+
const follow = shouldFollow === undefined || shouldFollow(node, n, graph);
26+
if (!follow) return;
2827

2928
depthFirstVisit(graph, nodeList, visited, visiting, n, opts);
3029
});

src/algorithms/depthFirstSearch/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export type DepthFirstSearchOptions<Node, LinkProps> = {
2727
* @param graph the graph instance being explored
2828
* @returns boolean
2929
*/
30-
visit?: (
30+
shouldFollow?: (
3131
source: NoInfer<Node>,
3232
target: NoInfer<Node>,
3333
graph: Graph<Node, LinkProps>,

0 commit comments

Comments
 (0)