javascript - recursive JSON.stringify implementation -


i trying learn recursion in javascript, figured i'd rewrite native json.stringify function using recursion challenge myself. got code work:

var my_stringify = function(obj){           value = obj[ object.keys(obj)[0] ];   index = object.keys(obj)[0];    delete obj[ object.keys(obj)[0] ];    // value simple string, not nested object   if (typeof value === 'string'){     if (object.keys(obj).length !== 0){       // continue recursion ..       return '"' + index + '":"' + value + '",' + my_stringify(obj);     }      // base case string @ end. stop recursion.     return '"' + index + '":"' + value + '"}';   }   // value nested object   else{          if (object.keys(obj).length !== 0){     // continue recursion ..       return '"' + index + '":{' + my_stringify(value) + ',' + my_stringify(obj);     }     // base case nested object @ end. stringify , end recursion.     return '"' + index + '":{' + my_stringify(value) + '}';     } } 

except fact first { in answer missing, , can't figure out how fix bug.

e.g. my_stringify({foo: 'bar'}) returns "foo":"bar"} instead of {"foo":"bar"}.

also, i'm aware i'm destroying original object, there way send on recursion reduced version of original object without deleting (something obj.slice(1))?

any advice appreciated !

new answer old question

there's painfully bad answers here fail under simplest examples. answer aims answer question exhaustively , demonstrate how approach scales when handling wide variety of data types , ...

corner cases

this function simple case analysis on non-null data's constructor property , encodes accordingly. manages cover lot of corner cases you're unlikely consider, such as

  • json.stringify(undefined) returns undefined
  • json.stringify(null) returns 'null'
  • json.stringify(true) returns 'true'
  • json.stringify([1,2,undefined,4]) returns '[1,2,null,4]'
  • json.stringify({a: undefined, b: 2}) returns '{ "b": 2 }'
  • json.stringify({[undefined]: 1}) returns '{ "undefined": 1 }'
  • json.stringify({a: /foo/}) returns { "a": {} }

so verify our stringifyjson function works properly, i'm not going test output of directly. instead, i'm going write little test method ensures json.parse of our encoded json returns our original input value

// care json.parse can work our result // output value should match input value // if doesn't, did wrong in our stringifier const test = data => {   return console.log(json.parse(stringifyjson(data))) }  test([1,2,3])     // should return [1,2,3] test({a:[1,2,3]}) // should return {a:[1,2,3]} 

disclaimer: should obvious code i'm share not meant used actual replacement json.stringify – there's countless corner cases didn't address. instead, code shared provide demonstration how go such task. additional corner cases added function.


runnable demo

without further ado, here stringifyjson in runnable demo verifies excellent compatibility several common cases

const stringifyjson = data => {    if (data === undefined)      return undefined    else if (data === null)      return 'null'    else if (data.constructor === string)      return '"' + data.replace(/"/g, '\\"') + '"'    else if (data.constructor === number)      return string(data)    else if (data.constructor === boolean)      return data ? 'true' : 'false'    else if (data.constructor === array)      return '[ ' + data.reduce((acc, v) => {        if (v === undefined)          return [...acc, 'null']        else          return [...acc, stringifyjson(v)]      }, []).join(', ') + ' ]'    else if (data.constructor === object)      return '{ ' + object.keys(data).reduce((acc, k) => {        if (data[k] === undefined)          return acc        else          return [...acc, stringifyjson(k) + ':' + stringifyjson(data[k])]      }, []).join(', ') + ' }'    else      return '{}'  }    // round-trip test , log console  const test = data => {    return console.log(json.parse(stringifyjson(data)))  }    test(null)                               // null  test('he said "hello"')                  // 'he said "hello"'  test(5)                                  // 5  test([1,2,true,false])                   // [ 1, 2, true, false ]  test({a:1, b:2})                         // { a: 1, b: 2 }  test([{a:1},{b:2},{c:3}])                // [ { a: 1 }, { b: 2 }, { c: 3 } ]  test({a:[1,2,3], c:[4,5,6]})             // { a: [ 1, 2, 3 ], c: [ 4, 5, 6 ] }  test({a:undefined, b:2})                 // { b: 2 }  test({[undefined]: 1})                   // { undefined: 1 }  test([[["test","mike",4,["jake"]],3,4]]) // [ [ [ 'test', 'mike', 4, [ 'jake' ] ], 3, 4 ] ]


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

android - Keyboard hides my half of edit-text and button below it even in scroll view -

css - Make div keyboard-scrollable in jQuery Mobile? -