Преобразование объекта и / или вложенного массива с объектами в допустимое строковое представление JSON без использования JSON .stringify? - PullRequest
0 голосов
/ 28 апреля 2020

У меня проблемы с выводом действительной строки JSON из объекта в качестве входных данных без использования JSON .stringify ().

Вот моя текущая полная реализация -

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"}

Я чувствую, что я близко, но что-то отсутствует в моей логике c, я начал с этого для долго и нужно некоторое руководство.

Если я смогу заставить мой объектный кодер работать, я уверен, что смогу рекурсивно использовать его для проверки более сложных входных данных, таких как:

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

Связанный вопрос, который я задал для массива JSON строка была решена здесь

Ответы [ 2 ]

3 голосов
/ 28 апреля 2020

Основная проблема заключается в том, что вам нужно поставить " s вокруг целого ключа при итерации по записям и вызвать my_json_encode для value:

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

Вам также необходимо, чтобы каждая пара ключ-значение, как указано выше, была объединена с помощью ,, что можно легко сделать, сопоставив каждую пару ключ-значение с указанной строкой, а затем .join(',') с их помощью.

Вы также должны экранировать любые " s в ключах или строковых значениях с помощью обратной косой черты sh. Также обратите внимание, что typeof является оператором, а не функцией - вы можете использовать его как 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}}]));
2 голосов
/ 28 апреля 2020

Для объектов вы можете сделать temp массивом и просто соединить с ним пары pu sh key: my_json_encode(value), затем соединить их с , и вывести { и } вокруг результата:

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}}]));
...