Skip to content

Commit ccf5e63

Browse files
kapetanJames Halliday
authored andcommitted
Added options.replacer for custom object serialization
1 parent 9ad5deb commit ccf5e63

File tree

3 files changed

+115
-6
lines changed

3 files changed

+115
-6
lines changed

index.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = function (obj, opts) {
66
var space = opts.space || '';
77
if (typeof space === 'number') space = Array(space+1).join(' ');
88
var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;
9+
var replacer = opts.replacer || function(key, value) { return value; };
910

1011
var cmp = opts.cmp && (function (f) {
1112
return function (node) {
@@ -18,27 +19,33 @@ module.exports = function (obj, opts) {
1819
})(opts.cmp);
1920

2021
var seen = [];
21-
return (function stringify (node, level) {
22+
return (function stringify (parent, key, node, level) {
2223
var indent = space ? ('\n' + new Array(level + 1).join(space)) : '';
2324
var colonSeparator = space ? ': ' : ':';
2425

2526
if (node && node.toJSON && typeof node.toJSON === 'function') {
2627
node = node.toJSON();
2728
}
29+
30+
node = replacer.call(parent, key, node);
31+
32+
if (node === undefined) {
33+
return;
34+
}
2835
if (typeof node !== 'object' || node === null) {
2936
return json.stringify(node);
3037
}
3138
if (isArray(node)) {
3239
var out = [];
3340
for (var i = 0; i < node.length; i++) {
34-
var item = stringify(node[i], level+1);
41+
var item = stringify(node, i, node[i], level+1) || json.stringify(null);
3542
out.push(indent + space + item);
3643
}
3744
return '[' + out.join(',') + indent + ']';
3845
}
3946
else {
4047
if (seen.indexOf(node) !== -1) {
41-
if (cycles) return stringify('__cycle__');
48+
if (cycles) return json.stringify('__cycle__');
4249
throw new TypeError('Converting circular structure to JSON');
4350
}
4451
else seen.push(node);
@@ -47,15 +54,19 @@ module.exports = function (obj, opts) {
4754
var out = [];
4855
for (var i = 0; i < keys.length; i++) {
4956
var key = keys[i];
50-
var keyValue = stringify(key,0)
57+
var value = stringify(node, key, node[key], level+1);
58+
59+
if(!value) continue;
60+
61+
var keyValue = json.stringify(key)
5162
+ colonSeparator
52-
+ stringify(node[key],level+1)
63+
+ value;
5364
;
5465
out.push(indent + space + keyValue);
5566
}
5667
return '{' + out.join(',') + indent + '}';
5768
}
58-
})(obj, 0);
69+
})({ '': obj }, '', obj, 0);
5970
};
6071

6172
var isArray = Array.isArray || function (x) {

test/replacer.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
var test = require('tape');
2+
var stringify = require('../');
3+
4+
test('replace root', function (t) {
5+
t.plan(1);
6+
7+
var obj = { a: 1, b: 2, c: false };
8+
var replacer = function(key, value) { return 'one'; };
9+
10+
t.equal(stringify(obj, { replacer: replacer }), '"one"');
11+
});
12+
13+
test('replace numbers', function (t) {
14+
t.plan(1);
15+
16+
var obj = { a: 1, b: 2, c: false };
17+
var replacer = function(key, value) {
18+
if(value === 1) return 'one';
19+
if(value === 2) return 'two';
20+
return value;
21+
};
22+
23+
t.equal(stringify(obj, { replacer: replacer }), '{"a":"one","b":"two","c":false}');
24+
});
25+
26+
test('replace with object', function (t) {
27+
t.plan(1);
28+
29+
var obj = { a: 1, b: 2, c: false };
30+
var replacer = function(key, value) {
31+
if(key === 'b') return { d: 1 };
32+
if(value === 1) return 'one';
33+
return value;
34+
};
35+
36+
t.equal(stringify(obj, { replacer: replacer }), '{"a":"one","b":{"d":"one"},"c":false}');
37+
});
38+
39+
test('replace with undefined', function (t) {
40+
t.plan(1);
41+
42+
var obj = { a: 1, b: 2, c: false };
43+
var replacer = function(key, value) {
44+
if(value === false) return;
45+
return value;
46+
};
47+
48+
t.equal(stringify(obj, { replacer: replacer }), '{"a":1,"b":2}');
49+
});
50+
51+
test('replace with array', function (t) {
52+
t.plan(1);
53+
54+
var obj = { a: 1, b: 2, c: false };
55+
var replacer = function(key, value) {
56+
if(key === 'b') return ['one', 'two'];
57+
return value;
58+
};
59+
60+
t.equal(stringify(obj, { replacer: replacer }), '{"a":1,"b":["one","two"],"c":false}');
61+
});
62+
63+
test('replace array item', function (t) {
64+
t.plan(1);
65+
66+
var obj = { a: 1, b: 2, c: [1,2] };
67+
var replacer = function(key, value) {
68+
if(value === 1) return 'one';
69+
if(value === 2) return 'two';
70+
return value;
71+
};
72+
73+
t.equal(stringify(obj, { replacer: replacer }), '{"a":"one","b":"two","c":["one","two"]}');
74+
});

test/str.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,27 @@ test('simple object', function (t) {
66
var obj = { c: 6, b: [4,5], a: 3, z: null };
77
t.equal(stringify(obj), '{"a":3,"b":[4,5],"c":6,"z":null}');
88
});
9+
10+
test('object with undefined', function (t) {
11+
t.plan(1);
12+
var obj = { a: 3, z: undefined };
13+
t.equal(stringify(obj), '{"a":3}');
14+
});
15+
16+
test('array with undefined', function (t) {
17+
t.plan(1);
18+
var obj = [4, undefined, 6];
19+
t.equal(stringify(obj), '[4,null,6]');
20+
});
21+
22+
test('object with empty string', function (t) {
23+
t.plan(1);
24+
var obj = { a: 3, z: '' };
25+
t.equal(stringify(obj), '{"a":3,"z":""}');
26+
});
27+
28+
test('array with empty string', function (t) {
29+
t.plan(1);
30+
var obj = [4, '', 6];
31+
t.equal(stringify(obj), '[4,"",6]');
32+
});

0 commit comments

Comments
 (0)