如何从对象中删除递归的未定义属性 - 同时保留构造函数链? [英] How to delete recursively undefined properties from an object - while keeping the constructor chain?

查看:66
本文介绍了如何从对象中删除递归的未定义属性 - 同时保留构造函数链?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个类似于如何使用lodash从对象中删除未定义和空值?。但是,那里提出的解决方案并不保留构造函数。除此之外,我想只删除那些以'_'开头的键。

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 addition to that, I want to only delete those keys which starts, say with '_'.

这是我要找的东西,似乎无法设法从lodash获得:

Here is what I am looking for, and can't seem to manage to get from lodash :

输入: new Cons({key1:'value1',key2:{key21:'value21',_ key22: undefined},key3:undefined,_ key4:undefined})

输出:
{key1:' value1',key2:{key21:'value21'},key3:undefined}

其中例如 function Cons (obj){_。extend(this,obj)}

我有 omitBy 使用lodash,但是,我松开了构造函数信息(即我不能再使用 instanceof Cons 来区分对象构造函数)。 forIn 看起来像是递归遍历的一个很好的候选者,但它只为我提供。我还需要路径才能删除对象(未设置)。

I have a solution with omitBy using lodash, however, I loose the constructor information (i.e. I cannot use instanceof Cons anymore to discriminate the object constructor). forIn looked like a good candidate for the recursive traversal but it only provides me with the value and the key. I also need the path in order to delete the object (with unset).

请注意:


  • 对象是任何有效的javascript对象

  • 构造函数是任何 javascript有效构造函数,该对象随附已经设置的构造函数。

  • 生成的对象必须具有 instanceof whatevertheconstructorwas 仍然是

  • the object is any valid javascript object
  • the constructor is any javascript valid constructor, and the object comes with the constructor already set.
  • the resulting object must have instanceof whatevertheconstructorwas still true

是否有更好的解决方案(使用lodash或其他方式)?

Is there a better solution (with lodash or else)?

推荐答案

您可以通过使用创建一个递归省略键的函数omitBy() mapValues()作为递归遍历键的辅助功能。另请注意,这也支持具有嵌套数组的对象的数组遍历或具有嵌套对象的顶级数组。

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] === '_'));
}

示例:

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}

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>

更新

您可以改变对象本身通过使用每个()并通过 unset()解决删除问题。

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}

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>

这篇关于如何从对象中删除递归的未定义属性 - 同时保留构造函数链?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆