-
-
Save kylebakerio/9e466eec0efdd0994b92 to your computer and use it in GitHub Desktop.
function stringifyJSON(subject) { | |
var output = ''; | |
var type = typeof subject; | |
if (type === 'number') { | |
return subject.toString(); | |
} else if (subject === null) { | |
return 'null'; | |
} else if (type === "boolean") { | |
return subject.toString(); | |
} else if (type === "string") { | |
return ('"' + (subject) + '"') | |
} else if (Object.prototype.toString.call(subject) === '[object Array]') { | |
var index = subject.length; | |
output += '['; | |
subject.forEach(function(val){ | |
if (typeof val === "number") { | |
// because for some reason we stringify numbers outside of the arrays, | |
// but not inside the arrays... ok... talk about a 'gotcha'. O_o; | |
output += val; | |
} else { | |
// let all other values in the array be stringified according to the rules above. | |
output += stringifyJSON(val); | |
} | |
index--; | |
if (index > 0) {output = output.concat(",")} | |
}); | |
output += ']'; | |
return output; | |
} else if (Object.prototype.toString.call(subject) === '[object Object]') { | |
var index = Object.keys(subject).length; | |
output += '{'; | |
for (var key in subject) { | |
if ( !((key === 'functions') || (key === "undefined")) ) { | |
output += (stringifyJSON(key) + ":" + stringifyJSON(subject[key])) | |
index--; | |
if (index > 0) { output += "," } | |
} | |
} | |
output += '}'; | |
} | |
return output; | |
} | |
///test values | |
var stringifiableObjects = [ | |
9, | |
null, | |
true, | |
false, | |
"Hello world", | |
[], | |
[8], | |
["hi"], | |
[8, "hi"], | |
[1, 0, -1, -0.3, 0.3, 1343.32, 3345, 0.00011999999999999999], | |
[8, [[],3,4]], | |
[[[["foo"]]]], | |
{}, | |
{"a": "apple"}, | |
{"foo": true, "bar": false, "baz": null}, | |
{"boolean, true": true, "boolean, false": false, "null": null }, | |
// basic nesting | |
{"a":{"b":"c"}}, | |
{"a":["b", "c"]}, | |
[{"a":"b"}, {"c":"d"}], | |
{"a":[],"c": {}, "b": true} | |
]; | |
var unstringifiableValues = [ | |
{ | |
'functions': function(){}, | |
'undefined': undefined | |
} | |
]; | |
// | |
// start tests | |
// | |
var passed = 0, failed = 0; | |
unstringifiableValues.concat(stringifiableObjects).reverse().forEach(function(val){ | |
JSON.stringify(val) === stringifyJSON(val) ? | |
passed++ : (failed++, | |
console.log("what type is it? " + typeof val), | |
console.log(Object.prototype.toString.call(val)), | |
// console.log("which statement did it hit? " + hit); | |
console.log("original input to be stringified:"), | |
console.dir(val), | |
console.log("which should be turned into:"), | |
console.dir(JSON.stringify(val)), | |
console.log("this is what my script currently turns it into:"), | |
console.dir(stringifyJSON(val)), | |
console.log("---- \n") | |
) | |
}) | |
console.log("Passed " + passed + " out of " + (passed + failed) + "; failed " + failed) |
working on it test by test
much prettier test results.
last shows up first, now.
also has test counter.
supper baffled at {}
right now... for some reason, even though Object.prototype.toString.call({}) === '[object Array]'
is false (it returns [object Object]...), it somehow passes that conditional statement and runs the array block...
Like, wtf? I don't feel tired enough to assume I'm screwing up some basic logic, but I can't imagine how else I could be getting this wrong...
edit: saved it as a variable right there and outputted it... somehow { }
is getting turned in to [ ]
. Well that's just all kinds of fun!
...WTF.
O_o
Ok, so, I think I am actually hitting a bug, because now after some slight changes that should have zero relevance to this (declaring some troubleshooting variables, removing "reverse()" from the execution context...), it is now hitting the 'string' section, not the 'array' section. so, something about the prior forEach loops being run must affect the context?
Sure enough, when I make it run the forEach loop in reverse()
again, it now hits the array block...
edit... the plot gets thicker... I was thinking something was modified somehow in my environment by running everything through a loop, but... when I run console.dir(stringifyJ(stringifiableObjects[12]))
directly, and set the stringifyJ
function to console.log(hit)
, it still shows it as hitting the array
block... so, that must mean that something in stringifyJ itself mutates it into array brackets... right?
....right?
except... sticking console.log(subject)
right after the block show it as being {}
...
SOLUTION:
it was never setting the 'hit' variable when the {}
value was going through the function... but just returning the hit value from the previous time. the section of the function that was supposed to set hit
as bottom
was broken.
Should have thought to check that. one more little piece of experience gained. figured it out by trying to run console.log
statements, while not doing a for loop (because that would have the prior object logging in there, since they were correctly going through the array loop), and noticing they weren't running, leading me to wonder if there were somehow a possibility that it wasn't running at all.
The reason it showed hit
as being array
even when I called it alone, is because technically I was calling it after I had just called it on every other stringifiable object, and so it was leftover from the prior forEach loop. I didn't have a clean testing environment, in other words; I was being lazy and using the same environment without commenting out my old code.
So, the hazards of 'global variables'. Old news, I guess. experience gained.
Troubleshooting step I missed: when I saw that it was impossible for it to be entering that block, because I knew the statement would be false, I should have doubted the system that told me it was entering the block (which is code I wrote).
Now passing 17/20
passed 20. recursion is a beautiful thing.
there are more tests... needs to do things with undefined and functions... adding those tests...
now it passes 21 out of 21. and that actually now passes the mocha test suite. that took longer than it should have, but great learning experience.
Went back and polished both the code and the text, after lessons learned from making a ternary version.
has a nice built in self tester now.