Skip to content

Commit 875028c

Browse files
committed
Implement graph and query with cursor
1 parent 4652cc8 commit 875028c

1 file changed

Lines changed: 106 additions & 0 deletions

File tree

JavaScript/1-graph.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
'use strict';
2+
3+
class Vertex {
4+
constructor(graph, data) {
5+
this.graph = graph;
6+
this.data = data;
7+
this.links = new Map();
8+
}
9+
link(...args) {
10+
const distinct = new Set(args);
11+
const links = this.links;
12+
const keyField = this.graph.keyField;
13+
let item, key;
14+
for (item of distinct) {
15+
key = item.data[keyField];
16+
links.set(key, null);
17+
}
18+
return this;
19+
}
20+
}
21+
22+
class Cursor {
23+
constructor(vertices) {
24+
this.vertices = vertices;
25+
}
26+
linked(...names) {
27+
const vertices = this.vertices;
28+
const result = new Set();
29+
let vertex, condition, name;
30+
for (vertex of vertices) {
31+
condition = true;
32+
for (name of names) {
33+
condition = condition && vertex.links.has(name);
34+
}
35+
if (condition) result.add(vertex);
36+
}
37+
return new Cursor(result);
38+
}
39+
}
40+
41+
class Graph {
42+
constructor(keyField) {
43+
this.keyField = keyField;
44+
this.vertices = new Map();
45+
}
46+
add(data) {
47+
const vertex = new Vertex(this, data);
48+
const key = data[this.keyField];
49+
if (this.vertices.get(key) === undefined) {
50+
this.vertices.set(key, vertex);
51+
}
52+
return vertex;
53+
}
54+
select(query) {
55+
const vertices = new Set();
56+
let vertex, condition, data, field;
57+
for (vertex of this.vertices.values()) {
58+
condition = true;
59+
data = vertex.data;
60+
if (data) {
61+
for (field in query) {
62+
condition = condition && data[field] === query[field];
63+
}
64+
if (condition) vertices.add(vertex);
65+
}
66+
}
67+
return new Cursor(vertices);
68+
}
69+
}
70+
71+
// Usage
72+
73+
const graph = new Graph('name');
74+
75+
const marcus = graph.add(
76+
{ name: 'Marcus Aurelius', city: 'Rome', born: 121, dynasty: 'Antonine' }
77+
);
78+
const lucius = graph.add(
79+
{ name: 'Lucius Verus', city: 'Rome', born: 130, dynasty: 'Antonine' }
80+
);
81+
const pius = graph.add(
82+
{ name: 'Antoninus Pius', city: 'Lanuvium', born: 86, dynasty: 'Antonine' }
83+
);
84+
const hadrian = graph.add(
85+
{ name: 'Hadrian', city: 'Santiponce', born: 76, dynasty: 'Nerva–Trajan' }
86+
);
87+
const trajan = graph.add(
88+
{ name: 'Trajan', city: 'Sevilla', born: 98, dynasty: 'Nerva–Trajan' }
89+
);
90+
91+
marcus.link(lucius);
92+
lucius.link(trajan, marcus, marcus, marcus);
93+
pius.link(marcus, lucius);
94+
hadrian.link(trajan);
95+
trajan.link(lucius, marcus);
96+
97+
console.dir({ graph }, { depth: null });
98+
99+
const res = graph
100+
.select({ city: 'Rome', dynasty: 'Antonine' })
101+
.linked('Trajan');
102+
103+
console.log('\nQuery result:\n');
104+
for (const item of res.vertices) {
105+
console.dir(item.data);
106+
}

0 commit comments

Comments
 (0)