I need to parse a JSON string such as that shown below:
var json =
"{\
foo: {\
bar: 'something',\
baz: {\
jack: 'other',\
jill: 5\
},\
bob: {\
bill: 'hello',\
bilbo: 11,\
baggins: {\
fizz: 'buzz'\
}\
}\
}\
}";
I can't use eval
or a JS library to parse this into a JavaScript object. All I have available to me are the methods of String, Object, etc.
The result of the parsing should be a JS object whose properties correspond to those of the JSON. The values of the JSON properties will only ever be numbers string or other objects, i.e. no arrays.
I'm really struggling with this, so if anyone could help me get started (or already has a pletely solution), it would be much appreciated.
I need to parse a JSON string such as that shown below:
var json =
"{\
foo: {\
bar: 'something',\
baz: {\
jack: 'other',\
jill: 5\
},\
bob: {\
bill: 'hello',\
bilbo: 11,\
baggins: {\
fizz: 'buzz'\
}\
}\
}\
}";
I can't use eval
or a JS library to parse this into a JavaScript object. All I have available to me are the methods of String, Object, etc.
The result of the parsing should be a JS object whose properties correspond to those of the JSON. The values of the JSON properties will only ever be numbers string or other objects, i.e. no arrays.
I'm really struggling with this, so if anyone could help me get started (or already has a pletely solution), it would be much appreciated.
Share Improve this question asked Jun 26, 2011 at 15:02 PawelPawel 211 silver badge1 bronze badge 18-
2
This seems a pletely pointless task. Even json2.js uses
eval
. – lonesomeday Commented Jun 26, 2011 at 15:07 - 3 Uh, it's homework guys. Thats why he can't use the native JSON stuff. – ryber Commented Jun 26, 2011 at 15:09
- 3 Your example is not valid JSON; the names of object name/value pairs need to be strings. And the backslash-line-break is also not allowed in JavaScript. – Gumbo Commented Jun 26, 2011 at 15:19
- 2 @Endophage: You’re wrong. In JSON, the names must be strings (see syntax diagram on json or RFC 4627). And a backspace in JavaScript strings must not be followed by a line terminator (see string literals syntax in the ECMAScript specification). – Gumbo Commented Jun 26, 2011 at 15:30
-
2
@Endophage: JSON is not JavaScript and vice versa. JSON is a data-interchange format and JavaScript is a programming language. What you are referring to is an object literal notation in JavaScript, but it’s not JSON. jQuery is written in JavaScript but not in JSON.
{foo:"bar"}
is valid JavaScript but it’s invalid in JSON asfoo
needs to be quoted as well. – Gumbo Commented Jun 26, 2011 at 17:47
4 Answers
Reset to default 4var json = Function("return {\
foo: {\
bar: 'something',\
baz: {\
jack: 'other',\
jill: 5\
},\
bob: {\
bill: 'hello',\
bilbo: 11,\
baggins: {\
fizz: 'buzz'\
}\
}\
}\
}")(); // object
Building upon phihag's answer, I just made this up. It might be a start for you.
It does not support:
- Spaces outside key/value
- Any of
,{}:"
as key/value - Arrays
- No error handling
- (Probably more - I haven't tested this extensively)
The code:
var json = '{"a":{"b":"test"},"c":123,"d":{"nested":{"key":null}}}';
var split = function(str, delimiter, func) {
var res = [];
var before = 0;
for(var i = 0; i < str.length; i++) {
if(str[i] === delimiter) {
if(func(str, i) === true) {
res.push(str.substring(before, i));
before = i + 1;
}
}
}
res.push(str.substring(before));
return res;
};
var amountbefore = function(str, pos, character) {
var amount = 0;
for(var i = 0; i < pos; i++) {
if(str[i] === character) {
amount++;
}
}
return amount;
};
var parse = function(obj) {
var stripped = obj.slice(1, -1);
var splitted = split(stripped, ",", function(str, i) {
return amountbefore(str, i, "{") === amountbefore(str, i, "}");
});
var res = {};
if(stripped === "") return res;
for(var i = 0; i < splitted.length; i++) {
var spl = split(splitted[i], ":", function(str, i) {
return amountbefore(str, i, "{") === amountbefore(str, i, "}")
});
var val;
if(spl[1][0] === "n") val = null;
if(/^\d/.test(spl[1][0])) val = spl[1] - 0;
if(spl[1][0] === "\"") val = spl[1].slice(1, -1);
if(spl[1][0] === "{") val = parse(spl[1]);
res[spl[0].slice(1, -1)] = val;
}
return res;
};
parse(json); // parses the JSON string
Luckily, JSON is very easy to parse: Just write parsing functions for each construct. For example, here's one that parses null
:
function parseNull(input, position) {
if (input.substr(position, 4) != "null") throw "Cannot parse as null";
return {result:null, position: position+4};
}
Implement a similar function for each construct, i.e. parseString
, parseArray
, parseObject
, ... .
Given these functions, write a function parse
that skips white-space and decides which of the above functions to call based on the first non white-space character. If that's n
, call parseNull
, if {
, call parseObject
etc. . Note that parseArray
and parseObject
will call parse
themselves.
There may be reasons to use a custom JSON parsing method but in case this was what you were looking for...
JavaScript has this all built in for you.
Here's an example:
var json = JSON.parse('{"myKey":"myValue"}');
console.log(json); // {myKey:'myValue'}