Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bae4688

Browse files
committed
add crud methods taking array of keys/vertices as arguments, significant refactor of Graph class to give vertices a separate value prop from their identifying key
1 parent 2c78eb3 commit bae4688

File tree

4 files changed

+315
-40
lines changed

4 files changed

+315
-40
lines changed

‎dist/datastructures/Graph.js

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,35 @@ const Queue_1 = __importDefault(require("./Queue"));
1010
;
1111
;
1212
class Graph {
13-
constructor() {
14-
this.addVertex = (name, value = null) => {
15-
const vertex = { key: name, value: value };
16-
if (!this.adjacencyList[name])
17-
this.adjacencyList[name] = [];
18-
if (!this.vertices[name])
19-
this.vertices[name] = vertex;
20-
return this.adjacencyList[name];
13+
constructor(options={direction: 'bi'},vertices) {
14+
this.addVertex = (key, value = null) => {
15+
const vertex = { key: key, value: value };
16+
if (!this.adjacencyList[key])
17+
this.adjacencyList[key] = [];
18+
if (!this.vertices[key])
19+
this.vertices[key] = vertex;
20+
return this.adjacencyList[key];
2121
};
22-
this.addEdge = (firstKey, secondKey, options = { direction: 'bi' }) => {
22+
this.addVertices = (vertices) => {
23+
switch (typeof vertices[0]) {
24+
case 'string':
25+
for (let v of vertices) {
26+
this.addVertex(v);
27+
}
28+
break;
29+
case 'object':
30+
for (let v of vertices) {
31+
let { key, value } = v;
32+
this.addVertex(key, value);
33+
}
34+
break;
35+
default:
36+
throw new TypeError('Incorrect type passed for vertices array. Try a key string or vertex object');
37+
}
38+
};
39+
this.addEdge = (firstKey, secondKey) => {
2340
// bidirectional
24-
const { direction } = options;
41+
const { direction } = this.options;
2542
if (!this.adjacencyList[firstKey] || !this.adjacencyList[secondKey]) {
2643
return null; // maybe throw error instead?
2744
}
@@ -33,8 +50,11 @@ class Graph {
3350
}
3451
return this.adjacencyList;
3552
};
36-
this.removeEdge = (firstKey, secondKey, options = { direction: 'bi' }) => {
37-
const { direction } = options;
53+
this.addEdges = (edges) => {
54+
edges.forEach(([fromKey, toKey]) => this.addEdge(fromKey, toKey));
55+
};
56+
this.removeEdge = (firstKey, secondKey) => {
57+
const { direction } = this.options;
3858
const firstEdge = this.adjacencyList[firstKey].findIndex((key) => key === secondKey);
3959
if (firstEdge !== -1) {
4060
this.adjacencyList[firstKey].splice(firstEdge, 1);
@@ -47,10 +67,10 @@ class Graph {
4767
}
4868
return this.adjacencyList;
4969
};
50-
this.removeVertex = (key,options={direction: 'bi'}) => {
70+
this.removeVertex = (key) => {
5171
if (this.adjacencyList[key] === undefined)
52-
returnnull;
53-
const { direction } = options;
72+
thrownewReferenceError(`Key: ${key} does not exist as a vertex.`);
73+
const { direction } = this.options;
5474
if (direction === 'bi') {
5575
for (let edge of this.adjacencyList[key]) {
5676
this.adjacencyList[edge] = this.adjacencyList[edge].filter(v => v !== key);
@@ -64,6 +84,13 @@ class Graph {
6484
}
6585
}
6686
delete this.adjacencyList[key];
87+
delete this.vertices[key];
88+
return this.adjacencyList;
89+
};
90+
this.removeVertices = (keys) => {
91+
for (let key of keys) {
92+
this.removeVertex(key);
93+
}
6794
return this.adjacencyList;
6895
};
6996
this.depthFirstTraversal = (startKey, map = v => v) => {
@@ -132,7 +159,25 @@ class Graph {
132159
};
133160
this.adjacencyList = {};
134161
this.vertices = {};
135-
// TODO: change directional to boolean and have it be set in constructor
162+
this.options = options;
163+
if (vertices) {
164+
switch (typeof vertices[0]) {
165+
case 'string':
166+
for (let v of vertices) {
167+
this.addVertex(v);
168+
}
169+
break;
170+
case 'object':
171+
for (let v of vertices) {
172+
let { key, value } = v;
173+
this.addVertex(key, value);
174+
}
175+
break;
176+
default:
177+
throw new TypeError('Incorrect type passed for vertices array. Try a key string or vertex object');
178+
}
179+
}
136180
}
181+
;
137182
}
138183
exports.default = Graph;

‎dist/datastructures/Graph.test.js

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('basic graph functionality', () => {
3535
test('add vertex method exists', () => {
3636
expect(typeof graph.addVertex).toBe('function');
3737
});
38-
test('can add vertex and it will appear as a key value pair in the adjacency list, with edges value initialized as empty array', () => {
38+
test(`can add vertex and it will appear as a key value pair in the adjacency list, with edges value initialized as empty array`, () => {
3939
graph.addVertex('Alice');
4040
expect(graph.adjacencyList['Alice']).toEqual([]);
4141
});
@@ -81,6 +81,97 @@ describe('basic graph functionality', () => {
8181
expect(graph.adjacencyList['March Hare']).toEqual(['Mad Hatter', 'Dormouse']);
8282
expect(graph.adjacencyList['Dormouse']).toEqual(['Mad Hatter', 'March Hare']);
8383
});
84+
test('can remove multiple vertices by key[] with removeVertices method', () => {
85+
populateGraph(graph);
86+
graph.removeVertices(['Dormouse', 'Mad Hatter', 'March Hare']);
87+
expect(graph.adjacencyList).toEqual({
88+
"Alice": ["Cheshire Cat"],
89+
"Cheshire Cat": ["Alice"], "Time": []
90+
});
91+
expect(graph.vertices).toEqual({
92+
"Alice": { "key": "Alice", "value": null },
93+
"Cheshire Cat": { "key": "Cheshire Cat", "value": null },
94+
"Time": { "key": "Time", "value": null }
95+
});
96+
});
97+
test('removing a non-existent key from graph throws reference error', () => {
98+
populateGraph(graph);
99+
try {
100+
graph.removeVertex('White Rabbit');
101+
}
102+
catch (e) {
103+
expect(typeof e).toEqual('object');
104+
expect(e.message).toBe("Key: White Rabbit does not exist as a vertex.");
105+
}
106+
try {
107+
graph.removeVertices(['White Rabbit', 'Queen of Hearts']);
108+
}
109+
catch (e) {
110+
expect(typeof e).toEqual('object');
111+
expect(e.message).toBe("Key: White Rabbit does not exist as a vertex.");
112+
}
113+
});
114+
});
115+
describe(`can pass in array values to graph's crud methods`, () => {
116+
test('can initiate a graph with values by passing string[] to constructor', () => {
117+
graph = new Graph_1.default({ direction: 'bi' }, ['Alice', 'The Caterpillar', 'The Cheshire Cat']);
118+
expect(graph.adjacencyList).toEqual({ "Alice": [], "The Caterpillar": [], "The Cheshire Cat": [] });
119+
expect(graph.vertices).toEqual({
120+
"Alice": { "key": "Alice", "value": null },
121+
"The Caterpillar": { "key": "The Caterpillar", "value": null },
122+
"The Cheshire Cat": { "key": "The Cheshire Cat", "value": null }
123+
});
124+
});
125+
test('can initiate a graph with values by passing vertex[] to constructor', () => {
126+
graph = new Graph_1.default({ direction: 'bi' }, [{ key: 'Alice', value: "Curiouser and curiouser!" },
127+
{ key: 'The Eaglet', value: "Speak English!" },
128+
{ key: 'The Dodo', value: "The best way to explain it is to do it." }]);
129+
expect(graph.adjacencyList).toEqual({ "Alice": [], "The Dodo": [], "The Eaglet": [] });
130+
expect(graph.vertices).toEqual({
131+
"Alice": { "key": "Alice", "value": "Curiouser and curiouser!" },
132+
"The Dodo": { "key": "The Dodo", "value": "The best way to explain it is to do it." },
133+
"The Eaglet": { "key": "The Eaglet", "value": "Speak English!" }
134+
});
135+
});
136+
test('addVertices method exists', () => {
137+
expect(typeof graph.addVertices).toBe('function');
138+
});
139+
test('can pass string array to addVertices and get proper result', () => {
140+
graph.addVertices(['Alice', 'The Duck', 'The Lory', 'The Eaglet']);
141+
expect(graph.adjacencyList).toEqual({
142+
"Alice": [], "The Duck": [],
143+
"The Eaglet": [], "The Lory": []
144+
});
145+
expect(graph.vertices).toEqual({
146+
"Alice": { "key": "Alice", "value": null },
147+
"The Duck": { "key": "The Duck", "value": null },
148+
"The Eaglet": { "key": "The Eaglet", "value": null },
149+
"The Lory": { "key": "The Lory", "value": null }
150+
});
151+
});
152+
test('addEdges method exists', () => {
153+
expect(typeof graph.addEdges).toBe('function');
154+
});
155+
test('bidirectional graph: can pass string array to addEdges, which it will interpret as a tuple: [fromKey, toKey]', () => {
156+
graph = new Graph_1.default({ direction: 'bi' }, [{ key: 'Alice', value: "Curiouser and curiouser!" },
157+
{ key: 'The Eaglet', value: "Speak English!" },
158+
{ key: 'The Dodo', value: "The best way to explain it is to do it." }]);
159+
graph.addEdges([['Alice', 'The Eaglet'], ['Alice', 'The Dodo'], ['The Eaglet', 'The Dodo']]);
160+
expect(graph.adjacencyList).toEqual({
161+
"Alice": ["The Eaglet", "The Dodo"],
162+
"The Dodo": ["Alice", "The Eaglet"], "The Eaglet": ["Alice", "The Dodo"]
163+
});
164+
});
165+
test('monodirectional graph: can pass string array to addEdges, which it will interpret as a tuple: [fromKey, toKey]', () => {
166+
graph = new Graph_1.default({ direction: 'mono' }, [{ key: 'Alice', value: "Curiouser and curiouser!" },
167+
{ key: 'The Eaglet', value: "Speak English!" },
168+
{ key: 'The Dodo', value: "The best way to explain it is to do it." }]);
169+
graph.addEdges([['Alice', 'The Eaglet'], ['Alice', 'The Dodo'], ['The Eaglet', 'The Dodo']]);
170+
expect(graph.adjacencyList).toEqual({
171+
"Alice": ["The Eaglet", "The Dodo"],
172+
"The Dodo": [], "The Eaglet": ["The Dodo"]
173+
});
174+
});
84175
});
85176
describe('depth first traversal of graphs', () => {
86177
test('DFS method exists', () => {

‎src/datastructures/Graph.test.ts

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('basic graph functionality', () => {
3535
test('add vertex method exists', () => {
3636
expect(typeof graph.addVertex).toBe('function');
3737
});
38-
test('can add vertex and it will appear as a key value pair in the adjacency list, with edges value initialized as empty array', () => {
38+
test(`can add vertex and it will appear as a key value pair in the adjacency list, with edges value initialized as empty array`, () => {
3939
graph.addVertex('Alice');
4040
expect(graph.adjacencyList['Alice']).toEqual([]);
4141
});
@@ -55,7 +55,7 @@ describe('basic graph functionality', () => {
5555
expect(graph.addEdge('Alice', 'Cheshire Cat')).toBeNull(); // Cheshire cat still invisible
5656
graph.addVertex('Cheshire Cat'); // appears!
5757
expect(typeof graph.addEdge('Alice', 'Cheshire Cat')).toBe('object');
58-
})
58+
});
5959
test('adding a vertex using existing key name will return the existing list of edges', () => {
6060
graph.addVertex('Alice');
6161
graph.addVertex('The Duchess');
@@ -81,6 +81,97 @@ describe('basic graph functionality', () => {
8181
expect(graph.adjacencyList['March Hare']).toEqual(['Mad Hatter', 'Dormouse']);
8282
expect(graph.adjacencyList['Dormouse']).toEqual(['Mad Hatter', 'March Hare'])
8383
});
84+
test('can remove multiple vertices by key[] with removeVertices method', () => {
85+
populateGraph(graph);
86+
graph.removeVertices(['Dormouse', 'Mad Hatter', 'March Hare']);
87+
expect(graph.adjacencyList).toEqual({
88+
"Alice": ["Cheshire Cat"],
89+
"Cheshire Cat": ["Alice"], "Time": []
90+
});
91+
expect(graph.vertices).toEqual({
92+
"Alice": { "key": "Alice", "value": null },
93+
"Cheshire Cat": { "key": "Cheshire Cat", "value": null },
94+
"Time": { "key": "Time", "value": null }
95+
});
96+
});
97+
test('removing a non-existent key from graph throws reference error', () => {
98+
populateGraph(graph);
99+
try {
100+
graph.removeVertex('White Rabbit');
101+
} catch (e) {
102+
expect(typeof e).toEqual('object');
103+
expect(e.message).toBe("Key: White Rabbit does not exist as a vertex.");
104+
}
105+
try {
106+
graph.removeVertices(['White Rabbit', 'Queen of Hearts']);
107+
} catch (e) {
108+
expect(typeof e).toEqual('object');
109+
expect(e.message).toBe("Key: White Rabbit does not exist as a vertex.");
110+
}
111+
})
112+
});
113+
114+
describe(`can pass in array values to graph's crud methods`, () => {
115+
test('can initiate a graph with values by passing string[] to constructor', () => {
116+
graph = new Graph({ direction: 'bi' }, ['Alice', 'The Caterpillar', 'The Cheshire Cat']);
117+
expect(graph.adjacencyList).toEqual({ "Alice": [], "The Caterpillar": [], "The Cheshire Cat": [] });
118+
expect(graph.vertices).toEqual({
119+
"Alice": { "key": "Alice", "value": null },
120+
"The Caterpillar": { "key": "The Caterpillar", "value": null },
121+
"The Cheshire Cat": { "key": "The Cheshire Cat", "value": null }
122+
});
123+
});
124+
test('can initiate a graph with values by passing vertex[] to constructor', () => {
125+
graph = new Graph({ direction: 'bi' }, [{ key: 'Alice', value: "Curiouser and curiouser!" },
126+
{ key: 'The Eaglet', value: "Speak English!" },
127+
{ key: 'The Dodo', value: "The best way to explain it is to do it." }]);
128+
expect(graph.adjacencyList).toEqual({ "Alice": [], "The Dodo": [], "The Eaglet": [] });
129+
expect(graph.vertices).toEqual({
130+
"Alice": { "key": "Alice", "value": "Curiouser and curiouser!" },
131+
"The Dodo": { "key": "The Dodo", "value": "The best way to explain it is to do it." },
132+
"The Eaglet": { "key": "The Eaglet", "value": "Speak English!" }
133+
});
134+
});
135+
test('addVertices method exists', () => {
136+
expect(typeof graph.addVertices).toBe('function');
137+
});
138+
test('can pass string array to addVertices and get proper result', () => {
139+
graph.addVertices(['Alice', 'The Duck', 'The Lory', 'The Eaglet']);
140+
expect(graph.adjacencyList).toEqual({
141+
"Alice": [], "The Duck": [],
142+
"The Eaglet": [], "The Lory": []
143+
});
144+
expect(graph.vertices).toEqual({
145+
"Alice": { "key": "Alice", "value": null },
146+
"The Duck": { "key": "The Duck", "value": null },
147+
"The Eaglet": { "key": "The Eaglet", "value": null },
148+
"The Lory": { "key": "The Lory", "value": null }
149+
});
150+
});
151+
152+
test('addEdges method exists', () => {
153+
expect(typeof graph.addEdges).toBe('function');
154+
});
155+
test('bidirectional graph: can pass string array to addEdges, which it will interpret as a tuple: [fromKey, toKey]', () => {
156+
graph = new Graph({ direction: 'bi' }, [{ key: 'Alice', value: "Curiouser and curiouser!" },
157+
{ key: 'The Eaglet', value: "Speak English!" },
158+
{ key: 'The Dodo', value: "The best way to explain it is to do it." }]);
159+
graph.addEdges([['Alice', 'The Eaglet'], ['Alice', 'The Dodo'], ['The Eaglet', 'The Dodo']]);
160+
expect(graph.adjacencyList).toEqual({
161+
"Alice": ["The Eaglet", "The Dodo"],
162+
"The Dodo": ["Alice", "The Eaglet"], "The Eaglet": ["Alice", "The Dodo"]
163+
});
164+
});
165+
test('monodirectional graph: can pass string array to addEdges, which it will interpret as a tuple: [fromKey, toKey]', () => {
166+
graph = new Graph({ direction: 'mono' }, [{ key: 'Alice', value: "Curiouser and curiouser!" },
167+
{ key: 'The Eaglet', value: "Speak English!" },
168+
{ key: 'The Dodo', value: "The best way to explain it is to do it." }]);
169+
graph.addEdges([['Alice', 'The Eaglet'], ['Alice', 'The Dodo'], ['The Eaglet', 'The Dodo']]);
170+
expect(graph.adjacencyList).toEqual({
171+
"Alice": ["The Eaglet", "The Dodo"],
172+
"The Dodo": [], "The Eaglet": ["The Dodo"]
173+
});
174+
})
84175
});
85176

86177
describe('depth first traversal of graphs', () => {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /