Recursively remove null values from JavaScript object

前端 未结 8 844
挽巷
挽巷 2020-12-28 16:07

I have a JSON obj, after some operations (like delete some pieces), I print it and everything looks good except that I have some null values. How do I remove th

相关标签:
8条回答
  • 2020-12-28 16:21

    I use the code here

    Remove empty elements from an array in Javascript

    then you could call it like

    JSON.stringify(obj.clean(null), null, 2)

    You would need to modify the code to work with objects too (or use the code as is inside the objects)

    0 讨论(0)
  • 2020-12-28 16:23

    I had to solve a similar problem, however I wanted to remove not only null values but also undefined, NaN, empty String, empty array and empty object values, recursively, by inspecting nested objects and also nested arrays.

    The following function is using Lo-Dash:

    function pruneEmpty(obj) {
      return function prune(current) {
        _.forOwn(current, function (value, key) {
          if (_.isUndefined(value) || _.isNull(value) || _.isNaN(value) ||
            (_.isString(value) && _.isEmpty(value)) ||
            (_.isObject(value) && _.isEmpty(prune(value)))) {
    
            delete current[key];
          }
        });
        // remove any leftover undefined values from the delete 
        // operation on an array
        if (_.isArray(current)) _.pull(current, undefined);
    
        return current;
    
      }(_.cloneDeep(obj));  // Do not modify the original object, create a clone instead
    }
    

    For example, if you invoke the method with the following input object:

    var dirty = {
      key1: 'AAA',
      key2: {
        key21: 'BBB'
      },
      key3: {
        key31: true,
        key32: false
      },
      key4: {
        key41: undefined,
        key42: null,
        key43: [],
        key44: {},
        key45: {
          key451: NaN,
          key452: {
            key4521: {}
          },
          key453: [ {foo: {}, bar:''}, NaN, null, undefined ]
        },
        key46: ''
      },
      key5: {
        key51: 1,
        key52: '  ',
        key53: [1, '2', {}, []],
        key54: [{ foo: { bar: true, baz: null }}, { foo: { bar: '', baz: 0 }}]
      },
      key6: function () {}
    };
    

    It'll recursively discard all the "bad" values, keeping in the end only the ones that carry some information.

    var clean = pruneEmpty(dirty);
    console.log(JSON.stringify(clean, null, 2));
    
    {
      key1: 'AAA',
      key2: {
        key21: 'BBB'
      },
      key3: {
        key31: true,
        key32: false
      },
      key5: {
        key51: 1,
        key52: '  ',
        key53: [1, '2'],
        key54: [{ foo: { bar: true }}, { foo: { baz: 0 }}]
      }
    };
    

    Hope it helps!

    0 讨论(0)
  • 2020-12-28 16:29

    We can use JSON.stringify and JSON.parse together to recursively remove blank attributes from an object.

    jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
                   if (value == null || value == '' || value == [] || value == {})
                       return undefined;
                   return value;
               });
    
    0 讨论(0)
  • 2020-12-28 16:32

    How do you deletes your pieces ?

    Delete an array element with the delete operator leaves a hole in the array. Instead, you should use Array.splice which can remove properly an element from array.

    0 讨论(0)
  • 2020-12-28 16:39
    // Iterate the array from back to front, removing null entries
    for (var i=obj.store.book.length;i--;){
      if (obj.store.book[i]===null) obj.store.book.splice(i,1);
    }
    

    If you want to remove all null values recursively from both objects and arrays:

    // Compact arrays with null entries; delete keys from objects with null value
    function removeNulls(obj){
      var isArray = obj instanceof Array;
      for (var k in obj){
        if (obj[k]===null) isArray ? obj.splice(k,1) : delete obj[k];
        else if (typeof obj[k]=="object") removeNulls(obj[k]);
      }
    }
    

    Seen in action:

    var o = {
      "store": {
        "book": [
           null,
           {
             "category": "fiction",
             "author": "Evelyn Waugh",
             "title": "Sword of Honour",
             "price": 12.99
           },
           null,
           {
              "category": "fiction",
              "author": "J. R. R. Tolkien",
              "title": "The Lord of the Rings",
              "isbn": "0-395-19395-8",
              "price": 22.99
           }
        ],
        "bicycle": {
           "color": "red",
           "bad": null,
           "price": 19.95
        }
      }
    }
    
    removeNulls(o);
    
    console.log(JSON.stringify(o,null,2));
    // {
    //   "store": {
    //     "book": [
    //       {
    //         "category": "fiction",
    //         "author": "Evelyn Waugh",
    //         "title": "Sword of Honour",
    //         "price": 12.99
    //       },
    //       {
    //         "category": "fiction",
    //         "author": "J. R. R. Tolkien",
    //         "title": "The Lord of the Rings",
    //         "isbn": "0-395-19395-8",
    //         "price": 22.99
    //       }
    //     ],
    //     "bicycle": {
    //       "color": "red",
    //       "price": 19.95
    //     }
    //   }
    // }
    
    0 讨论(0)
  • 2020-12-28 16:40

    The following is a modification to the answer by @Phrogz. If book[3] was also null, the answer given would not remove the last null because the array's length would be less than k in last loop's iteration.

    The following would work by performing a second call to the array:

    function removeNulls(obj) {
      var isArray = obj instanceof Array;
      for (var k in obj) {
        if (obj[k] === null) isArray ? obj.splice(k, 1) : delete obj[k];
        else if (typeof obj[k] == "object") removeNulls(obj[k]);
        if (isArray && obj.length == k) removeNulls(obj);
      }
      return obj;
    }
    
    0 讨论(0)
提交回复
热议问题