-
Notifications
You must be signed in to change notification settings - Fork 1
/
search.js
103 lines (93 loc) · 2.94 KB
/
search.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
export { SuffixTree, all_words_in_name }
class suffixTreeNode {
constructor() {
this.children = {};
this.results = new Set();
}
}
class SuffixTree {
constructor(case_sensitive = false) {
this.root = new suffixTreeNode();
this.case_sensitive = case_sensitive;
}
add(key, result) {
for (let i = 0; i < key.length; i++) {
this.insertSuffix(key.substring(i), result, i);
}
}
insertSuffix(suffix, result, index) {
if (!this.case_sensitive)
suffix = suffix.toLowerCase();
let node = this.root;
for (let i = 0; i < suffix.length; i++) {
let char = suffix[i];
if (!node.children[char]) {
node.children[char] = new suffixTreeNode();
}
node = node.children[char];
node.results.add(result);
}
}
search_pattern(pattern) {
if (!this.case_sensitive)
pattern = pattern.toLowerCase();
let node = this.root;
for (let i = 0; i < pattern.length; i++) {
let char = pattern[i];
if (!node.children[char]) {
return new Set(); // no results
}
node = node.children[char];
}
return node.results;
}
search_all_words(string) {
/* return the set intersection of a pattern search for each word in string */
let words = string.split(' ');
let results = null;
for (let i in words) {
let word = words[i];
if (i == 0) {
results = this.search_pattern(word);
}
else if (word.trim().length > 0) {
results = intersection(results, this.search_pattern(word));
}
}
return Array.from(results);
}
}
function all_words_in_name(string, name, case_sensitive = false) {
/* return true if all words of string are in name
use this when you don't need the data structure,
e.g. if you are loading names one by one */
if (!case_sensitive)
{
string = string.toLowerCase();
name = name.toLowerCase();
}
let words = string.split(' ');
for (let i in words) {
let word = words[i];
if (!name.includes(word)) {
return false;
}
}
return true;
}
function intersection(set1, set2) {
return new Set([...set1].filter(x => set2.has(x)));
}
function test() {
T = new SuffixTree();
T.add('banana', new SearchResult('banana', '-> banana link'));
T.add('fruit', new SearchResult('banana', '-> banana link'));
T.add('tomato', new SearchResult('tomato', '-> tomato link'));
T.add('fruit', new SearchResult('tomato', '-> tomato link'));
console.log(T.search_pattern('na'));
console.log(T.search_pattern('yjdgfjgf'));
console.log(T.search_pattern('fruit'));
console.log(T.search_all_words('to ma'));
console.log(T.search_all_words('to ma ba'));
}
//test()