使用 lodash 查找具有真值的 JS 对象属性

14

假设我有一个对象,如下:

var foo = {
    alpha: true,
    beta: false,
    gamma: true
}
我可以使用`_.findKey`方法获取一个值为true的键,但我真正想要的是获取一个包含所有值为true的键的数组。例如:
_.findAllKeys(foo, function(val) { return val; });
// yields -> ["alpha", "gamma"]

编写一个函数来完成这个任务非常简单,但似乎这是findKey的一个显而易见的概括。lodash是否有这样的函数?

7个回答

23

var foo = {
    alpha: true,
    beta: false,
    gamma: true
};

var t1 = _.keys(_.pick(foo, _.identity));
console.log(t1);

var t2 = _(foo).pick(_.identity).keys().value();
console.log(t2);
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

编辑:
正如@backdesk所指出的那样,_.pick在lodash 4中已不再可用,因为_.pickBy已被分离。

var foo = {
    alpha: true,
    beta: false,
    gamma: true
};

var t1 = _.keys(_.pickBy(foo, _.identity));
console.log(t1);

var t2 = _(foo).pickBy(_.identity).keys().value();
console.log(t2);

// _.pickBy defaults to _.identity

var t3 = _.keys(_.pickBy(foo));
console.log(t3);

var t4 = _(foo).pickBy().keys().value();
console.log(t4);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.8.2/lodash.min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>


顺便提一下,这并不是批评,但如果你希望实现透明度,使用lodash是行不通的 - 可以使用underscore。请改用pickBy。 - backdesk
@backdesk 谢谢,我已经更新了答案,注明了lodash 3和4之间的区别。 - dting

11

我找到了一个既感觉笨拙又优雅的答案。

var foo = {
    alpha: true,
    beta: false,
    gamma: true
};
_.invert(foo, true).true

// yields -> ["alpha", "gamma"]

1
哎呀,那很令人困惑。我可能会编写一个自定义函数,包装 _.invert(foo, true).true,你只需要在一个地方注释它正在做什么。而且你可以让函数的值更符合英语。 - Sumner Evans
1
假设您只想要字面上为“true”的值,而不是所有真值,那么这将起作用。 - Retsam
不错的想法。如果我在多个地方使用它,我会这样做。确实如此。在我的情况下,这可以工作,但对于非真值,它将无法工作。 - Asmor
这还有效吗?我现在只得到了字符串 "gamma" 的结果。 - Caleb Jay

5
我们可以使用lodash中的pickBy()来获取值为true的键。
const active = _.keys(_.pickBy(foo));

另外我们也可以使用以下方法:

var active = _.keys(foo).filter(function (id) {
    return foo[id]
});

4
在 loDash 中,pickBy 默认使用 _.identity 过滤属性,因此您可以像这样使用它:
_.pickBy({'a': undefined, 'b':1, c:{}});

// => Object {b: 1, c: Object}

2

只需尝试

var foo = {
    alpha: true,
    beta: false,
    gamma: true
}

_.pickBy(foo, _.identity);


1

我认为你正在寻找pick方法。

返回对象的副本,仅过滤出白名单键(或有效键的数组)的值。或者接受指示要选择哪些键的谓词。

var foo = {
    alpha: true,
    beta: false,
    gamma: true
};

var picked = _.pick(foo, function(value) { return value; });
console.log(picked);

$('#output').html(JSON.stringify(picked));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.js"></script>
<div id="output">
</div>


0

我个人更喜欢以下方式 - 即使它更冗长 - 因为我认为它更明显地表达了它的意思。不过,这需要使用es6语法:

_.toPairs(foo)
  .filter([key, value] => value)
  .map([key, value] => key);

如果您的 ESLint 不允许未使用的变量,您可以在 .eslint.yml 中使用以下内容:
rules:    
  no-unused-vars:
    - 2
    - vars: all
      args: after-used
      argsIgnorePattern: _$

这允许编写

_.toPairs(foo)
  .filter([key_, value] => value)
  .map([key, value_] => key);

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