Reputation: 5181
Let's say I have an object like:
var foo = {
alpha: true,
beta: false,
gamma: true
}
I can use _.findKey to get one key with a true value, but I'd really like to get an array containing all keys with a true value. E.g.
_.findAllKeys(foo, function(val) { return val; });
// yields -> ["alpha", "gamma"]
It's simple enough to write a function to do this, but it seems like such an obvious generalization of findKey that I feel I must just be missing it. Does lodash have such a function?
Upvotes: 14
Views: 18739
Reputation: 121
We can use pickBy() in lodash to get the key for which value equal to true.
const active = _.keys(_.pickBy(foo));
Alternatively we can also use,
var active = _.keys(foo).filter(function (id) {
return foo[id]
});
Upvotes: 5
Reputation: 541
Just try
var foo = {
alpha: true,
beta: false,
gamma: true
}
_.pickBy(foo, _.identity);
Upvotes: 2
Reputation: 13177
I personally prefer the following - even though it is more verbose - because I think it is more obvious what it does. It requires es6 syntax, though:
_.toPairs(foo)
.filter([key, value] => value)
.map([key, value] => key);
If your ESLint does not allow unused variables you can for instance use the following in .eslint.yml
:
rules:
no-unused-vars:
- 2
- vars: all
args: after-used
argsIgnorePattern: _$
Which allows to write
_.toPairs(foo)
.filter([key_, value] => value)
.map([key, value_] => key);
Upvotes: 0
Reputation: 571
pickBy in loDash by default uses _.identity
to filter properties
so you can use it like this:
_.pickBy({'a': undefined, 'b':1, c:{}});
// => Object {b: 1, c: Object}
Upvotes: 4
Reputation: 39287
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>
Edit:
As noted by @backdesk, _.pick
no longer works for lodash 4 because _.pickBy
was split out.
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>
Upvotes: 23
Reputation: 8980
I think you're looking for the pick
method.
Return a copy of the object, filtered to only have values for the whitelisted keys (or array of valid keys). Alternatively accepts a predicate indicating which keys to 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>
Upvotes: 1
Reputation: 5181
I found an answer which simultaneously feels kludgy and elegant.
var foo = {
alpha: true,
beta: false,
gamma: true
};
_.invert(foo, true).true
// yields -> ["alpha", "gamma"]
Upvotes: 11