forked from begriffs/objgrep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
objgrep.js
70 lines (66 loc) · 1.78 KB
/
objgrep.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
/*jslint browser: true, indent: 2, forin: true */
/*global toString, console */
(function () {
"use strict";
var mark = 'visited_by_objgrep',
objgrep = function (root, regex, depth, context) {
var className, ret = [], i, newContext;
context = context || '';
if (depth < 1) {
return [];
}
switch (typeof root) {
case 'string':
case 'number':
case 'boolean':
if (root.toString().match(regex)) {
return [context];
}
break;
case 'object':
if (!root || root.hasOwnProperty(mark)) {
return []; // cyclic
}
root[mark] = true;
for (i in root) {
if (i !== mark) {
if (i.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {
newContext = [context, i].join('.');
} else if (i.match(/^[0-9]+$/)) {
newContext = context + "[" + i + "]";
} else {
newContext = context + "['" + i + "']";
}
if (i.match(regex)) {
ret.push(newContext);
}
try {
ret = ret.concat(objgrep(
root[i],
regex,
depth - 1,
newContext
));
} catch (e) {
// if we cannot access a property, then so be it
}
}
}
delete root[mark];
break;
default:
break;
}
return ret;
};
Object.defineProperty(Object.prototype, 'grep', {
enumerable: false,
value: function (regex, depth, context) {
if (typeof depth !== "number") {
depth = 5;
console.log('Using a default search depth of ' + depth);
}
return objgrep(this, regex, depth, context);
}
});
})();