How to delete recursively undefined properties from an object - while keeping the constructor chain?

前端 未结 4 2436
醉酒成梦
醉酒成梦 2021-02-20 14:01

This is a question similar to How to remove undefined and null values from an object using lodash?. However, the solutions proposed there do not conserve the constructor. In add

4条回答
  •  南方客
    南方客 (楼主)
    2021-02-20 14:08

    You can create a function that recursively omits keys through the use of omitBy() and mapValues() as an assisting function for traversing keys recursively. Also note that this also supports array traversal for objects with nested arrays or top level arrays with nested objects.

    function omitByRecursively(value, iteratee) {
      var cb = v => omitByRecursively(v, iteratee);
      return _.isObject(value)
        ? _.isArray(value)
          ? _.map(value, cb)
          : _(value).omitBy(iteratee).mapValues(cb).value()
        : value;
    }
    
    function Cons(obj) { 
      _.extend(this, omitByRecursively(obj, (v, k) => k[0] === '_'));
    }
    

    Example:

    function omitByRecursively(value, iteratee) {
      var cb = v => omitByRecursively(v, iteratee);
      return _.isObject(value)
        ? _.isArray(value)
          ? _.map(value, cb)
          : _(value).omitBy(iteratee).mapValues(cb).value()
        : value;
    }
    
    function Cons(obj) { 
      _.extend(this, omitByRecursively(obj, (v, k) => k[0] === '_'));
    }
    
    var result = new Cons({
      key1 : 'value1', 
      key2 : {
        key21 : 'value21', 
        _key22: undefined
      }, 
      key3: undefined,
      _key4 : undefined,
      key5: [
        {
          _key: 'value xx',
          key7: 'value zz',
          _key8: 'value aa'
        }
      ]
    });
    
    console.log(result);
    .as-console-wrapper{min-height:100%;top:0}


    Update

    You can mutate the object itself by creating a function that recursively traverses the object with each() and settles the removal by unset().

    function omitByRecursivelyInPlace(value, iteratee) {
    
      _.each(value, (v, k) => {
    
        if(iteratee(v, k)) {
          _.unset(value, k); 
        } else if(_.isObject(v)) {
          omitByRecursivelyInPlace(v, iteratee);  
        }
    
      });
    
      return value;
    
    }
    
    function Cons(obj){_.extend(this, obj)}
    
    var result = omitByRecursivelyInPlace(instance, (v, k) => k[0] === '_');
    

    function omitByRecursivelyInPlace(value, iteratee) {
      
      _.each(value, (v, k) => {
        
        if(iteratee(v, k)) {
          _.unset(value, k); 
        } else if(_.isObject(v)) {
          omitByRecursivelyInPlace(v, iteratee);  
        }
        
      });
      
      return value;
      
    }
    
    function Cons(obj){_.extend(this, obj)}
    
    var instance = new Cons({
      key1 : 'value1', 
      key2 : {
        key21 : 'value21', 
        _key22: undefined
      }, 
      key3: undefined,
      _key4 : undefined,
      key5: [
        {
          _key: 'value xx',
          key7: 'value zz',
          _key8: 'value aa'
        }
      ]
    });
    
    var result = omitByRecursivelyInPlace(instance, (v, k) => k[0] === '_');
    
    console.log(result instanceof Cons);
    console.log(result);
    .as-console-wrapper{min-height:100%;top:0}

提交回复
热议问题