Last active
November 18, 2022 15:30
-
-
Save ctodmia/2883e2e8b321cd5cac37 to your computer and use it in GitHub Desktop.
Reimplementation of JSON.stringify
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//The following code is a reimplementation of the native Javascript method JSON.stringify | |
//keep reading for the though process that lead to the solution | |
var stringify = function(obj) { | |
//checks if the input obj is a function statement or undefined | |
if(typeof obj === 'undefined' || typeof obj === 'function') { | |
return undefined; | |
} | |
//checks if the input obj is a string | |
if(typeof obj === 'string') { | |
return '"' + obj + '"'; | |
} | |
//checks if the input obj is a array/nest array | |
if(Array.isArray(obj)) { | |
var newArray = []; | |
for(var i = 0; i < obj.length; i++) { | |
if(obj[i] === undefined || typeof obj[i] === 'function') { | |
newArray.push(stringify(null)); | |
} else { | |
newArray.push(stringify(obj[i])); | |
} | |
} | |
return '[' + newArray.join(',') + ']'; | |
} | |
//checks if the input obj is an object literal and if it is defined | |
if(obj && typeof obj === 'object') { | |
var newObjArray = []; | |
for(var key in obj) { | |
if(obj[key] !== undefined || typeof obj[key] !== 'function') { | |
newObjArray.push(stringify(key) + ":" + stringify(obj[key])); | |
} | |
} | |
return "{" + newObjArray.join(',') + "}"; | |
} | |
//will take care of any other edge cases such as numbers and null | |
return obj + ""; | |
}; | |
//Implementation and thought process | |
//The first thing I needed to do to solve this problem was find all the edge cases related to | |
//JSON.stringify. I used MDN for to explore the possibilities and limitations related to the method. | |
//I discovered the following: | |
// The proper implementation of my code should output the following: | |
//stringify({}); // '{}' | |
//stringify(true); // 'true' | |
//stringify('foo'); // '"foo"' | |
//stringify([1, 'false', false]); // '[1,"false",false]' | |
//stringify({ x: 5 }); // '{"x":5}' | |
//the function that I create must wrap quotes around the argument that is passed into it. | |
//The solution must take into account the following input values: | |
//strings - 'hello' | |
//numbers - 9; | |
//null - null | |
//booleans - true, false | |
//arrays/nested arrays - [], [9, 'hello'], [[[[[8]]]]], [7, []], 'hey'], [me: you, you: me] | |
//objects/nested objects - {}, ["a": {"b":"hello"}] etc | |
//***NOTE the following cannot be stringified. | |
//JSON.stringify(function(){}) // undefined | |
//JSON.stringify(undefined) // undefined | |
//JSON.stringify({false: undefined, function: function(){}}) // '{}' | |
//JSON.stringify([undefined, function(){}]) // "[null, null]" | |
//special characters cannot return anything and throw errors. For example: | |
//JSON.stringify(k) // ERROR: k is not defined | |
//JSON.stringify(:) //Uncaught SyntaxError: Unexpected token : | |
//the first thing is to write base cases for the inputs that I know I cannot stringify. | |
//I can use the typeof method to return undefined anytime the input is a function or undefine. | |
//I know that for numbers, booleans, null, I can return input + "" | |
//so for example | |
//9 + "" ==> "9" | |
//false + "" ==> "false" | |
//true + "" ==> "true" | |
//I also know that I can use the "typeof" property in javascript to determine if the input | |
//is a string | |
//so if the typeof input is a string I will return '"' + input '"' | |
//The next input type that I have to deal with are arrays. This is tricky because the | |
//javascript interpretter does not return the array that I am expecting. I can't just | |
//use the typeof to check if its an array because both arrays, objects and null will | |
//return object. So instead I use the Array.isArray() method. Next I found that I can't | |
//just wrap quotes around an empty array and get the desired result. | |
//For example: | |
//var in = []; | |
//'"' + in + '"' ==> '""' | |
//I can get around this by doing the following: | |
//var in = []; | |
//"[" + in + "]" ==> '[]' | |
//next I am going to deal with nested arrays. Again the javascript interpreter does not | |
//return the stringified arrays as I am expecting. For example I know my algorithm should | |
//do the following : | |
//stringify([1, 'false', false]); // '[1,"false",false]' | |
//But when I do run the code below here's what happens: | |
//var a = [1, "false", false]; | |
//"[" + a + "]" ==> '[1, false, false]' | |
//these results let me know that I have to iterate over each element in the array | |
//and check for its type. The best way to get internal quotes around the "false" | |
//is to recursively invoke my stringify function on each element and push the | |
//returned value into a new array. I can return the stringified version of my | |
//new array as | |
// "[" + newarray.join(',') + "]" | |
//Before pushing in an element to my new array I have to check if the element is undefined | |
//or a function because | |
//JSON.stringify([undefined, function(){}]) ==> "[null, null]" | |
//if the element within an array is undefined or a function I have to invoke the stringify function | |
//on null and push that result into my new array. | |
//Finally I need my code to deal with object literals. For an input to qualify as an | |
//object literal the type of input must be true and the input must return true. This | |
//will especially take care of cases in which input = null; since null and undefined | |
//will return false it will not qualify as an object literal. From here objects will | |
//be stringified similar to arrays | |
//I will iterate through each key in an object. I need to push the key and value into | |
//the the array in a very specific way. | |
//newarry.push(stringify(key) + ":" + stringify(obj[key])) | |
//then I would return the full stringified obj as followed: | |
//"{" + newarray.join(',') + "}" | |
//before pushing in the key/value I need to make sure it is neither a function nor | |
//undefine because: | |
//JSON.stringify({false: undefined, function: function(){}}) // '{}' | |
//my code will do nothing if the input is undefined or the typeof input is a function | |
//That should take care of the most obvious cases. Now for some pseudocode to outline | |
//my plan of attack : | |
//Create a function called stringify that takes an object as a arguement. | |
//check if the type of object is undefined or a function | |
//if yes return undefined | |
//check if the type of object is a string | |
//if its true return the stringified object | |
//check if the object is an array | |
//if true create a new array variable that is equal to an empty array | |
//iterate through the length of the object array | |
//if the element at a given index is undefined or a function | |
//recursion: invoke the stringify function on null and push the result into the new array | |
//else | |
//recursion: invoke the stringify function on the value at the given index | |
//and push the result into the new array | |
//return the concatenation of the new array with quoted brackets on each side. | |
//else check to see if the object is equal to true and the typeof function returns | |
//true for object | |
//if true, create a new array variable that is equal to an empty array | |
//iterate through each key in the object. | |
//if the obj[key] is NOT equal to undefined or the typeof obj[key] is NOT function | |
//recursion: invoke the stringify function on the key and the value and | |
//push formatted property into the new array | |
//return the concatenation of the new array with quoted curly braces on each side. | |
//after all checks return the obj plus "" to take care of all other edge cases such as | |
//numbers and booleans. | |
//To reiterate the solution is as followed: | |
//Create a function called stringify that takes an object as a arguement. | |
var stringify = function(obj) { | |
//check if the type of object is undefined or a function | |
if(typeof obj === 'undefined' || typeof obj === 'function') { | |
//if yes return undefined | |
return undefined; | |
} | |
//check if the type of object is a string | |
if(typeof obj === 'string') { | |
//if its true return the stringified object | |
return '"' + obj + '"'; | |
} | |
//checks if the input obj is a array/nest array | |
if(Array.isArray(obj)) { | |
//if true create a new array variable that is equal to an empty array | |
var newArray = []; | |
//iterate through each key in the object. | |
for(var i = 0; i < obj.length; i++) { | |
//if the element at a given index is undefined or a function | |
if(obj[i] === undefined || typeof obj[i] === 'function') { | |
//recursion: invoke the stringify function on null and push the result into the new array | |
newArray.push(stringify(null)); | |
} else { | |
//recursion: invoke the stringify function on the value at the given index | |
//and push the result into the new array | |
newArray.push(stringify(obj[i])); | |
} | |
} | |
//return the concatenation of the new array with quoted brackets on each side. | |
return '[' + newArray.join(',') + ']'; | |
} | |
//checks if the input obj is an object literal and if it is defined | |
if(obj && typeof obj === 'object') { | |
//if true, create a new array variable that is equal to an empty array | |
var newObjArray = []; | |
//iterate through each key in the object. | |
for(var key in obj) { | |
//if the obj[key] is NOT equal to undefined or the typeof obj[key] is NOT function | |
if(obj[key] !== undefined || typeof obj[key] !== 'function') { | |
//recursion: invoke the stringify function on the key and the value and | |
//push formatted property into the new array | |
newObjArray.push(stringify(key) + ":" + stringify(obj[key])); | |
} | |
} | |
//return the concatenation of the new array with quoted curly braces on each side. | |
return "{" + newObjArray.join(',') + "}"; | |
} | |
//will take care of any other edge cases such as numbers and null | |
return obj + ""; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment