ChatGPT解决这个技术问题 Extra ChatGPT

使用 Underscore.js 从 Object 中删除空属性/虚假值

我有一个具有多个属性的对象。我想删除任何具有虚假值的属性。

这可以通过数组上的 compact 来实现,但是对象呢?

为避免跨存储库复制粘贴此内容,您可以使用 Bitimport this component(其中有 3 个测试通过和 MIT 许可证)。您也可以尝试 this NPM package(这对于一个小组件来说可能有点过分了)。

C
Community

从 Underscore 版本 1.7.0 开始,您可以使用 _.pick

_.pick(sourceObj, _.identity)

解释

_.pick 的第二个参数可以是用于选择值的谓词函数。选择谓词返回 truthy 的值,忽略谓词返回 falsy 的值。

pick _.pick(object, *keys) 返回对象的副本,过滤后仅包含白名单键(或有效键数组)的值。或者接受一个谓词,指示选择哪些键。

_.identity 是一个辅助函数,它返回它的第一个参数,这意味着它也可以作为一个谓词函数来选择真值并拒绝假值。 Underscore 库还附带了许多其他谓词,例如 _.pick(sourceObj, _.isBoolean) 将仅保留布尔属性。

如果你经常使用这种技术,你可能想让它更有表现力:

var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);

Underscore 版本 1.6.0 也提供了 _.pick,但它不接受谓词函数而不是白名单。


特别感谢提到 _.identity 功能,非常好用。
这非常方便!也可以使用 _.omit(sourceObj, _.isUndefined) 仅删除未定义的值(允许 false、null、0)。
也可以执行 pick(obj, Boolean) 来消除错误值,当 arr.filter(Boolean) 清除数组中的错误值时,可以使用相同的方法......
在 ES6 中,这变成了 _.pick(sourceObj, prop => prop)
在 lodash 4.4.0 中,_.pick 与属性名称一起使用,对于帖子使用 _.pickBy 中提到的此功能
C
Community

您可以制作自己的下划线插件(mixin):

_.mixin({
  compactObject: function(o) {
    _.each(o, function(v, k) {
      if(!v) {
        delete o[k];
      }
    });
    return o;
  }
});

然后将其用作本机下划线方法:

var o = _.compactObject({
  foo: 'bar',
  a: 0,
  b: false,
  c: '',
  d: null,
  e: undefined
});

更新

@AndreiNeculau pointed out 一样,此 mixin 会影响原始对象,而原始 compact 下划线方法 returns a copy of the array
为了解决此问题并使我们的 compactObject 表现得更像它的表亲,这里有一个小更新:

_.mixin({
  compactObject : function(o) {
     var clone = _.clone(o);
     _.each(clone, function(v, k) {
       if(!v) {
         delete clone[k];
       }
     });
     return clone;
  }
});

由于该问题有一个下划线引用,因此最好提一下它的行为不像 _.compact。它将删除属性,而不是创建仅具有真实值的浅层克隆。请参阅下面的stackoverflow.com/a/19750822/465684
@AndreiNeculau 你是对的!我之前好像错过了。请参阅我的更新答案。
为什么首先复制一个对象的所有属性,然后遍历它们并删除虚假的?这表现不佳。此外,通常不鼓励使用 delete,因为它会立即从原型链中公开具有相同名称的属性,并且还会由于“隐藏类”(V8)而损害性能 - 更改对象结构会导致引擎做额外的工作。最好和最短的解决方案是_.pick(o, _.identity)
N
Nick Steele

快速清除:_.omitBy(source, i => !i);

这与埃米尔的回答相反。这样,恕我直言,读起来更清楚;它更不言自明。

如果您没有 ES6 的奢华,那么清洁度会稍差:_.omitBy( source, function(i){return !i;});

备选:_.omitBy(source, _.isEmpty)

使用 _.isEmpty 而不是 _.identity 来保证真实性,还可以方便地从集合中删除空数组和对象,并且可能不方便地删除数字和日期。因此,结果不是对 OP 问题的确切答案,但是在寻找删除空集合时它可能很有用。


在 Lodash 4.0 中,此功能现在位于 omitBy 下。 lodash.com/docs#omitBy
我相信这与避免否定的 _.pick(source, i => i); 相同
@JeffLowery 这在 Lodash 中更好,因为默认谓词是标识函数! _.pickBy(source) 就是所需要的。
注意:数字被认为是空的。 _.isEmpty(5) === true。因此,数字值将被删除。
B
Beau

使用 lodash 的 transform

_.transform(obj, function(res, v, k) {
  if (v) res[k] = v;
});

whit lodash 的 _.pick(obj, _.identity);短^_^
这个答案或@evilive 在它下面的评论就是答案。
根据上述评论,较短的变体将是 var compactObject = _.partialRight(_.pick, _.identity);
是的,您只需要 _.pickBy(object)
F
Florian Margaine
Object.keys(o).forEach(function(k) {
    if (!o[k]) {
        delete o[k];
    }
});

.keys.forEach 可以使用下划线。
那么这在 Underscore 中会是什么样子呢?试图拼凑起来……
+1 这是一个了不起的人。请给我JS的forEach方法的链接
w
webwise

您可以创建一个浅克隆:

_(obj).reduce(function(a,v,k){ 
     if(v){ a[k]=v; } 
     return a; 
},{});

g
gion_13

对于对象使用删除。

for(var k in obj){

  if(obj.hasOwnProperty(k) && !obj[k]){
    delete obj[k];
  }
}

因为他想要一个下划线解决方案,你可以使用下划线的方法之一迭代数组
M
Marco Godínez

突然间,我需要创建一个函数来递归地删除 falsies。我希望这有帮助。我正在使用 Lodash。

var removeFalsies = function (obj) {
    return _.transform(obj, function (o, v, k) {
        if (v && typeof v === 'object') {
            o[k] = _.removeFalsies(v);
        } else if (v) {
            o[k] = v;
        }
    });
};

_.mixin({ 'removeFalsies': removeFalsies });

然后你可以使用它:

var o = _.removeFalsies({
  foo: 'bar',
  a: 0,
  b: false,
  c: '',
  d: null,
  e: undefined,
  obj: {
    foo: 'bar',
    a: 0,
    b: false,
    c: '',
    d: null,
    e: undefined
  }
});

// {
//   foo: 'bar',
//   obj: {
//     foo: 'bar'
//   }
// }

G
Geoff Lee

要添加到 gion_13 的答案:

_.mixin({
  compactObject : function(o) {
     var newObject = {};
     _.each(o, function(v, k) {
       if(v !== null && v !== undefined) {
         newObject[k] = v
       }
     });
     return newObject;
  }
});

这个创建一个新对象并添加键和值,而不是克隆所有内容并删除键值对。细微差别。

但更重要的是,显式检查 null 和 undefined 而不是 false,这将删除具有 false 作为值的键值对。


H
Haseeb A

您应该使用 lodash 中的 pickBy

pickBy 的默认签名是 _.(sourceObj, [_.identity]),因此它将删除空属性

_.pickBy(sourceObj);

H
Hossein Rezaei

在 lodash 你这样做:

_.pickBy(object, _.identity);

t
tzvi

尽管记录了 _.compact 可在数组中使用。它似乎也适用于对象。我刚刚在 chrome、opera 和 firefox 控制台中运行了以下命令:

var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)

[1, 3, function()]

更新:由于示例表明在对象上调用 _.compact 将删除键并返回压缩数组。


但它仍然返回一个数组。钥匙丢了。
你是对的。那我要删除我的答案吗?还是stackoverflow更喜欢别的东西?
我不知道社区偏好,但如果您愿意离开它可能具有防止其他人添加类似答案的价值。