Skip to content

Commit 875028c

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

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy