基于值过滤对象属性

35

有没有一种优雅的方式使用lodash/underscore从这个对象中过滤掉falsey属性?类似于_.compact(array)从数组中删除falsey元素的方式

所以从

{
  propA: true,
  propB: true,
  propC: false,
  propD: true,
}

返回

{
  propA: true,
  propB: true,
  propD: true,
}

17
ES6 语法:Object.keys(obj).filter((key) => obj[key])翻译:获取对象中所有属性名,然后过滤出属性值为真的属性名。 - Dimitrije M
9
@DimitrijeM 这会返回一个键的数组,而不是一个对象。 - Scribblemacher
1
嘿@DimitrijeM,+1,你应该把这个放在答案里给更多的人看到吧?谢谢! - Ivan Chaer
8个回答

36
这里有两个纯JavaScript选项: A.:遍历对象的键并delete那些具有假值的键。

var obj = {
  propA: true,
  propB: true,
  propC: false,
  propD: true,
};

Object.keys(obj).forEach(key => {
  if (!obj[key]) delete obj[key];
});

console.log(obj);

请参阅Object.keys()Array.prototype.forEach()

B.:遍历对象的键,并将真值添加到新对象中。

var obj = {
  propA: true,
  propB: true,
  propC: false,
  propD: true,
};

var filteredObj = Object.keys(obj).reduce((p, c) => {    
  if (obj[c]) p[c] = obj[c];
  return p;
}, {});

console.log(filteredObj);

参见Object.keys()Array.prototype.reduce()


31

Lodash 4.0

Lodash 4.0有_.pick方法,它接收一个属性数组,还有_.pickBy方法,它接收一个函数作为参数,返回一个仅包含那些函数返回真值的键的对象,这就是我们想要的,所以它将是:

filtered = _.pickBy(obj, function(value, key) {return value;})

或者,由于_.pickBy默认将_.identity用作其第二个参数(这本质上就是我们上面编写的内容),因此它可以简单地编写为:

或者,由于_.pickBy默认使用_.identity作为第二个参数(这本质上就是我们上面编写的内容),因此它可以简单地写成:

filtered = _.pickBy(obj);

版本低于4.0的Underscore或Lodash

在underscore和旧版本的lodash中,只有一个_.pick函数,它既拥有_.pick的行为,也拥有v4中的_.pickWith的行为。所以你可以这样做:

filtered = _.pick(obj, function(value, key) {return value;})

更简洁地说:

filtered = _.pick(obj, _.identity)

4
正如评论中部分提到的,ES6 提供了 Object.entries() 和在 2019 年提供了 Object.fromEntries()
允许:
Object.fromEntries(Object.entries(obj).filter(([key, value]) => ...))

例:

const obj = {
  a: 12,
  b: 123,
};

const filteredObj = Object.fromEntries(
  Object.entries(obj).filter(
    ([_, value]) => value > 100
  )
);

console.log(filteredObj);
// {b: 123}

2

不幸的是,我还不能直接评论上面的帖子,所以我创建了这个额外的帖子。

自从 Lodash v4 版本后,上述描述的功能已经移至 _.pickBy。使用 _.identity 作为默认值,您也可以更改您的代码:

var filtered = _.pickBy(obj);

请查看此JSBin,其中包含一个可行示例。

1
如果您正在使用lodash,我建议使用以下代码:
var object = {
    propA: true,
    propB: true,
    propC: false,
    propD: true,
};

_.pick(object, _.identity);
// →
// {
//   propA: true,
//   propB: true,
//   propD: true
// }

pick()函数生成一个新对象,其中包括回调返回真值的属性。因此,我们可以将identity()函数用作回调,因为它只会返回每个属性值。


0
另一种方法
const objFilter = (obj, condition) => {
    let newObj = {}
    for (const [key, value] of Object.entries(obj)) {
        if (condition(value)) {
            newObj = { ...newObj, [key]: value }
        }
    }
    return newObj
}

像这样点燃:

const newData = objFilter(oldData, (value) => value.marked === false)

0
let temp = {
  propA: true,
  propB: true,
  propC: false,
  propD: true,
}

let obj = {}
for(x in temp){
   if(temp[x] == true){
     obj[x] = temp[x]
   }
}

console.log(obj)

使用 for-in 循环,我们可以像这样实现它。


1
这个问题特别要求使用lodash或underscore来执行。这也是一个五年前的问题,有一个被接受的答案,这意味着任何新的答案都应该指出它们所解决的问题的新方面。 - Jason Aller

0
从lodash 4开始,我们可以使用pickBy()方法仅获取值等于true的内容。
const active = _.keys(_.pickBy(object));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接