recursive JSON.stringify implementation

后端 未结 6 1817
被撕碎了的回忆
被撕碎了的回忆 2021-02-04 21:25

I am trying to learn recursion in Javascript, so I figured I\'d rewrite the native JSON.stringify function using recursion as a challenge to myself. I almost got my

6条回答
  •  庸人自扰
    2021-02-04 22:12

    I disagree with @Bergi's assertion that regular old recursion isn't a good fit for this. Like I said in my comment you can avoid the use of a for loop by passing the index as an argument to the function. This is a very common technique and prevents you from needing to copy or modify the data structure.

    Here's my stab at such an implementation. As you can see it's really straightforward (and to my own surprise, it works!):

    function jsonify(obj, idx) {
      var json, objStr = toString.call(obj);
    
      // Handle strings
      if(objStr == '[object String]') { return '"' + obj + '"' }
    
      idx = idx || 0
    
      // Handle arrays
      if(objStr == '[object Array]') {
        if(idx >= obj.length) {
          // The code below ensures we'll never go past the end of the array,
          // so we can assume this is an empty array
          return "[]"
        }
    
        // JSONify the value at idx
        json = jsonify( obj[idx] )
    
        if(idx < obj.length - 1) {
          // There are items left in the array, so increment the index and
          // JSONify the rest
          json = json + "," + jsonify( obj, idx + 1 )
        }
    
        // If this is the first item in the array, wrap the result in brackets
        if(idx === 0) { return "[" + json + "]" }
    
        return json
      }
    
      // Handle objects
      if(obj === Object(obj)) {
        var keys = Object.keys(obj)
        var key = keys[idx]
    
        // JSONify the key and value
        json = '"' + key + '":' + jsonify( obj[key] )
    
        if(idx < keys.length - 1) {
          // There are more keys, so increment the index and JSONify the rest
          return json + "," + jsonify( obj, idx + 1 )
        }
    
        // If this is the first key, wrap the result in curly braces
        if(idx === 0) { return "{" + json + "}" }
    
        return json
      }
    
      return obj.toString() // Naively handle everything else
    }
    
    var items = [ 9, "nine", { "key": [], "key2": { "subkey": 3.333 } } ]
    
    console.log("OUTPUT", jsonify(items))
    // => OUTPUT [9,"nine","key":[],"key2":{"subkey":3.333}]
    

    There are a number of ways this could be tightened up (and I'm sure there are some bugs, too), but you get the idea.

提交回复
热议问题