-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
75 lines (66 loc) · 3.3 KB
/
index.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
'use strict';
const { uniqWith, isEqual, intersection } = require('lodash');
function pruneExpression(expression) {
if (typeof expression === 'string') {
return expression;
} else if (expression.not) {
expression.not = pruneExpression(expression.not);
return expression;
} else if (expression.and) {
for (let i = 0; i < expression.and.length; i++) {
const andExpression = expression.and[i];
if (typeof andExpression === 'object' && andExpression.and) {
// Remove the nested 'and' expression and insert its contents
expression.and.splice(i, 1, ...andExpression.and);
i--; // bump counter back since we just inserted more items w/ the splice
} else if (typeof andExpression === 'object' && andExpression.or) {
// Check if there are any common variables between the base group and any nested "or" groups
const variablesInGroup = expression.and.filter(item => typeof item === 'string');
if (intersection(variablesInGroup, andExpression.or).length > 0) {
// Remove the nested 'or' expression as it is redundant
expression.and.splice(i, 1);
i--; // bump counter back since we just removed an element
} else {
expression.and[i] = pruneExpression(andExpression);
}
} else {
expression.and[i] = pruneExpression(andExpression);
}
}
expression.and = uniqWith(expression.and, isEqual);
// If there is only one element left after deduplication, just return that
if (expression.and.length === 1) {
return expression.and[0];
}
return expression;
} else if (expression.or) {
for (let i = 0; i < expression.or.length; i++) {
const orExpression = expression.or[i];
if (typeof orExpression === 'object' && orExpression.or) {
// Remove the nested 'or' expression and insert its contents
expression.or.splice(i, 1, ...orExpression.or);
// bump counter back since we just inserted more items w/ the splice
i--;
} else if (typeof orExpression === 'object' && orExpression.and) {
// Check if there are any common variables between the base group and any nested "and" groups
const variablesInGroup = expression.or.filter(item => typeof item === 'string');
if (intersection(variablesInGroup, orExpression.and).length > 0) {
// Remove the nested 'or' expression as it is redundant
expression.or.splice(i, 1);
i--; // bump counter back since we just removed an element
} else {
expression.or[i] = pruneExpression(orExpression);
}
} else {
expression.or[i] = pruneExpression(orExpression);
}
}
expression.or = uniqWith(expression.or, isEqual);
// If there is only one element left after deduplication, just return that
if (expression.or.length === 1) {
return expression.or[0];
}
return expression;
}
}
module.exports = pruneExpression;