EN
JavaScript - convert object to JSON with ordered properties
5 points
In this article we would like to show how in JavaScript create JSON from object that has ordered properties.
Quick solution:
xxxxxxxxxx
1
const isObject = (entry) => typeof entry === 'object';
2
3
const iterateKeys = (entry, callback) => {
4
const keys = Object.keys(entry);
5
for (const key of keys) {
6
callback(key, entry[key]);
7
};
8
};
9
10
const findKeys = (entry) => {
11
if (isObject(entry)) {
12
const keys = [];
13
const callback = (key, value) => {
14
keys.push(key);
15
if (isObject(value)) {
16
iterateKeys(value, callback);
17
}
18
};
19
iterateKeys(entry, callback);
20
return keys.sort();
21
}
22
return null;
23
};
24
25
const toJson = (object, indent) => {
26
const keys = findKeys(object);
27
return JSON.stringify(object, keys, indent);
28
};
29
30
31
// Usage example:
32
33
const indent = ' ';
34
35
const object = {
36
name: 'John', // <-------- it will be moved to 2nd position
37
age: 25, // <-------- it will be moved to 1st position
38
todos: [
39
'Lectures',
40
'Classes'
41
]
42
};
43
const json = toJson(object, indent);
44
45
console.log(json);
The solution in below example sorts properies before stringify operation.
Practical example:
xxxxxxxxxx
1
const escapeText = (text) => {
2
let result = '';
3
for (let i = 0; i < text.length; ++i) {
4
const code = text.charCodeAt(i);
5
switch (code) {
6
case 0x00: // \0 - NULL
7
case 0x01: case 0x02: case 0x03: case 0x04:
8
case 0x05: case 0x06: case 0x07: case 0x08:
9
continue;
10
case 0x09: // \t - TABULATOR
11
result += '\\t';
12
continue;
13
case 0x0A: // \n - NEW LINE
14
result += '\\n';
15
continue;
16
case 0x0B: case 0x0C:
17
continue;
18
case 0x0D: // \r - CARRIAGE RETURN
19
result += '\\r';
20
continue;
21
case 0x0E: case 0x0F: case 0x10: case 0x11:
22
case 0x12: case 0x13: case 0x14: case 0x15:
23
case 0x16: case 0x17: case 0x18: case 0x19:
24
case 0x1A: case 0x1B: case 0x1C: case 0x1D:
25
case 0x1E: case 0x1F:
26
continue;
27
// allowed characters: 0x20 and 0x21
28
case 0x22: // " - DOUBLE QUOTATION MARK
29
result += '\\"';
30
continue;
31
// allowed characters: 0x23 - 0x26
32
case 0x27: // ' - SINGLE QUOTATION MARK
33
result += '\'';
34
continue;
35
// allowed characters: 0x28 - 0x5B
36
case 0x5C: // \ - BACK SLASH
37
result += '\\\\';
38
continue;
39
default:
40
result += text[i];
41
}
42
}
43
return result;
44
};
45
46
const getType = (object) => {
47
return Object.prototype.toString.call(object);
48
};
49
50
const prettifyArray = (array, prefix, indent) => {
51
let result = '[\n';
52
for (let i = 0; i < array.length; ++i) {
53
const value = prettifyEntry(array[i], prefix + indent, indent);
54
if (i > 0) {
55
result += ',\n'
56
}
57
result += prefix + indent + value;
58
}
59
return result + '\n' + prefix + ']';
60
};
61
62
const prettifyObject = (object, prefix, indent) => {
63
let result = '{\n';
64
const keys = Object.keys(object);
65
for (const key of keys.sort()) {
66
const name = escapeText(key);
67
const value = prettifyEntry(object[key], prefix + indent, indent);
68
if (result.length > 2) {
69
result += ',\n'
70
}
71
result += prefix + indent + '"' + name + '": ' + value;
72
}
73
return result + '\n' + prefix + '}';
74
};
75
76
const prettifyEntry = (entry, prefix, indent) => {
77
const type = getType(entry);
78
switch(type) {
79
case '[object Array]':
80
return prettifyArray(entry, prefix, indent);
81
case '[object Object]':
82
return prettifyObject(entry, prefix, indent);
83
case '[object Null]':
84
return null;
85
case '[object Boolean]':
86
case '[object Number]':
87
case '[object BigInt]':
88
return entry;
89
case '[object String]':
90
return '"' + escapeText(entry) + '"';
91
default:
92
throw new Error(type + ' type is not permitted in json.');
93
}
94
};
95
96
const stringifyObject = (object, indent) => {
97
return prettifyEntry(object, '', indent || '\t');
98
};
99
100
// Usage example:
101
102
const indent = ' ';
103
104
const object = {
105
"name": "John",
106
"age": 25,
107
"todos": [
108
"Lectures",
109
"Classes"
110
]
111
};
112
const json = stringifyObject(object, indent);
113
114
console.log(json);