0

I'm having trouble outputting a valid JSON string from an object as input without using JSON.stringify().

Here is my current complete implementation -

var my_json_encode = function(input) {

  if(typeof(input) === "string"){
      return '"'+input+'"'
  }
  if(typeof(input) === "number"){
      return `${input}`
  }

  if(Array.isArray(input)) {
     const formatedArrayMembers = input.map(value => my_json_encode(value)).join(',');
     return `[${formatedArrayMembers}]`;
  }

  *****Trouble is here*******
  if(typeof(input) === "object" && !Array.isArray(input)) {
    let temp = "";
    for (let [key, value] of Object.entries(input)) {
            let val = `${key} : ${value}`;
            temp +=  my_json_encode(val)
    }
    return `{${temp}}`
  }
}
Current input is -> {"key1":"val1","key2":"val2"}
Expected output is -> {"key1":"val1","key2":"val2"}

Current output using object type check in my_json_encode -> {"key1 : val1""key2 : val2"}

I feel that I'm close but something is missing in my logic, I've started at this for to long and need some guidance.

If I can get my object encoder to work, I'm sure I can recursively use it to check more complicated inputs such as:

Expected Output-> [1,"a",{"key1":"value1","key2":null,"key3":[4,"b"],"key5":{"inner1":"innerval1","inner2":9}}]

Related question I asked for an array to JSON string was solved here

3
  • 1
    If you're only missing the comma between key/value pairs then why not simply change temp to an array, push your pairs to it as a string and then return with temp.join(',') ? Commented Apr 28, 2020 at 5:11
  • 1
    If this is just a learning exercise, this is great. But note that JSON.stringify handles quite a few edge cases not included here, things like rejecting circular data structures and not including undefined properties, functions, or Symbols, plus additional features such as a replacer function, pretty-printing, converting Infinity and NaN to null, and calling objects' .toJSON methods. A full replacement for all this is a non-trivial task. Commented Apr 28, 2020 at 13:09
  • Yes its a learning exercise, I'm in the process of interview prepping and this was a question that might be asked by companies. Commented Apr 29, 2020 at 0:14

2 Answers 2

3

The main issue is that you need to put "s around the whole key when iterating over the entries, and call my_json_encode on the value:

"${key}: ${my_json_encode(value)}"

You also need each key-value pair like above to be joined by ,, which can be done easily by mapping each key-value pair to the above sort of string, then .join(',')ing them.

You should also be escaping any "s in the keys or string values with a backslash. Also note that typeof is an operator, not a function - you can use it like typeof someVar:

var my_json_encode = function(input) {

  if (typeof input === "string") {
    return '"' + input.replace(/"/g, '\\"') + '"'
  }
  if (typeof input === "number") {
    return input;
  }

  if (Array.isArray(input)) {
    const formatedArrayMembers = input.map(my_json_encode).join(',');
    return `[${formatedArrayMembers}]`;
  }
  if (input === null) return 'null';
  // then it's a non-array object
  const keyValStrArray = Object.entries(input).map(([key, val]) => (
    `"${key.replace(/"/g, '\\"')}":${my_json_encode(val)}`
  ));
  return `{${keyValStrArray.join(',')}}`
};

console.log(my_json_encode({ "key1": "val1", "key2": "val2" }));
console.log(my_json_encode([1,"a",{"key1":"value1","key2":null,"key3":[4,"b"],"key5":{"inner1":"innerval1","inner2":9}}]));

Sign up to request clarification or add additional context in comments.

Comments

2

For objects, you can make temp an array and just push key: my_json_encode(value) pairs to it, then joining them with , and outputting { and } around the result:

var my_json_encode = function(input) {

  if (input === null) {
    return "null";
  }

  if (typeof(input) === "string") {
    return `"${input}"`;
  }
  if (typeof(input) === "number") {
    return `${input}`;
  }

  if (Array.isArray(input)) {
    const formatedArrayMembers = input.map(value => my_json_encode(value)).join(',');
    return `[${formatedArrayMembers}]`;
  }

  if (typeof(input) === "object") {
    let temp = [];
    for (let [key, value] of Object.entries(input)) {
      temp.push(`"${key}" : ${my_json_encode(value)}`);
    }
    return `{${temp.join(', ')}}`;
  }
}

console.log(my_json_encode({key1:"val1",key2:3}));
console.log(my_json_encode([1,"a",{"key1":"value1","key2":null,"key3":[4,"b"],"key5":{"inner1":"innerval1","inner2":9}}]));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.