Skip to content

Commit 3ec6776

Browse files
authored
Merge pull request #555 from streamich/json-walk
json-walk
2 parents 94c6e2c + 2a93536 commit 3ec6776

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@
236236
"json-text",
237237
"json-type",
238238
"json-type-value",
239+
"json-walk",
239240
"reactive-rpc",
240241
"util"
241242
]

src/json-walk/__tests__/index.spec.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {walk} from '..';
2+
3+
test('can walk through a value', () => {
4+
const value = {
5+
a: 1,
6+
foo: [2, 'a', null, 3, true, false, new Set([1, 2]), new Map([['b', 3]])],
7+
};
8+
const nodes: unknown[] = [];
9+
walk(value, (node) => {
10+
nodes.push(node);
11+
});
12+
expect(nodes).toEqual([
13+
value,
14+
1,
15+
value.foo,
16+
2,
17+
'a',
18+
null,
19+
3,
20+
true,
21+
false,
22+
new Set([1, 2]),
23+
1,
24+
2,
25+
new Map([['b', 3]]),
26+
3,
27+
]);
28+
});
29+
30+
test('can walk through null', () => {
31+
const value = null;
32+
const nodes: unknown[] = [];
33+
walk(value, (node) => {
34+
nodes.push(node);
35+
});
36+
expect(nodes).toEqual([null]);
37+
});
38+
39+
test('can walk empty object', () => {
40+
const value = {};
41+
const nodes: unknown[] = [];
42+
walk(value, (node) => {
43+
nodes.push(node);
44+
});
45+
expect(nodes).toEqual([{}]);
46+
});
47+
48+
test('can walk empty array', () => {
49+
const value: any[] = [];
50+
const nodes: unknown[] = [];
51+
walk(value, (node) => {
52+
nodes.push(node);
53+
});
54+
expect(nodes).toEqual([[]]);
55+
});

src/json-walk/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export const walk = (value: unknown, callback: (value: unknown) => void): void => {
2+
callback(value);
3+
if (typeof value === 'object') {
4+
if (!value) return;
5+
switch (value.constructor) {
6+
case Array: {
7+
const arr = value as unknown[];
8+
const length = arr.length;
9+
for (let i = 0; i < length; i++) walk(arr[i], callback);
10+
break;
11+
}
12+
case Object: {
13+
const obj = value as Record<string, unknown>;
14+
for (const key in obj) walk(obj[key], callback);
15+
break;
16+
}
17+
case Map:
18+
case Set: {
19+
const mapOrSet = value as Set<unknown> | Map<unknown, unknown>;
20+
mapOrSet.forEach((val) => walk(val, callback));
21+
break;
22+
}
23+
}
24+
}
25+
};

0 commit comments

Comments
 (0)