-
Notifications
You must be signed in to change notification settings - Fork 781
/
identical-links-same-purpose-after.js
106 lines (87 loc) · 2.6 KB
/
identical-links-same-purpose-after.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
104
105
106
/**
* Check if two given objects are the same (Note: this fn is not extensive in terms of depth equality)
* @param {Object} a object a, to compare
* @param {*} b object b, to compare
* @returns {Boolean}
*/
function isIdenticalObject(a, b) {
if (!a || !b) {
return false;
}
const aProps = Object.getOwnPropertyNames(a);
const bProps = Object.getOwnPropertyNames(b);
if (aProps.length !== bProps.length) {
return false;
}
const result = aProps.every(propName => {
const aValue = a[propName];
const bValue = b[propName];
if (typeof aValue !== typeof bValue) {
return false;
}
if (typeof aValue === `object` || typeof bValue === `object`) {
return isIdenticalObject(aValue, bValue);
}
return aValue === bValue;
});
return result;
}
function identicalLinksSamePurposeAfter(results) {
/**
* Skip, as no results to curate
*/
if (results.length < 2) {
return results;
}
/**
* Filter results for which `result` is undefined & thus `data`, `relatedNodes` are undefined
*/
const incompleteResults = results.filter(
({ result }) => result !== undefined
);
/**
* for each result
* - get other results with matching accessible name
* - check if same purpose is served
* - if not change `result` to `undefined`
* - construct a list of unique results with relatedNodes to return
*/
const uniqueResults = [];
const nameMap = {};
for (let index = 0; index < incompleteResults.length; index++) {
const currentResult = incompleteResults[index];
const { name, urlProps } = currentResult.data;
/**
* This is to avoid duplications in the `nodeMap`
*/
if (nameMap[name]) {
continue;
}
const sameNameResults = incompleteResults.filter(
({ data }, resultNum) => data.name === name && resultNum !== index
);
const isSameUrl = sameNameResults.every(({ data }) =>
isIdenticalObject(data.urlProps, urlProps)
);
/**
* when identical nodes exists but do not resolve to same url, flag result as `incomplete`
*/
if (sameNameResults.length && !isSameUrl) {
currentResult.result = undefined;
}
/**
* -> deduplicate results (for both `pass` or `incomplete`) and add `relatedNodes` if any
*/
currentResult.relatedNodes = [];
currentResult.relatedNodes.push(
...sameNameResults.map(node => node.relatedNodes[0])
);
/**
* Update `nodeMap` with `sameNameResults`
*/
nameMap[name] = sameNameResults;
uniqueResults.push(currentResult);
}
return uniqueResults;
}
export default identicalLinksSamePurposeAfter;