简体   繁体   中英

Find properties of JS object with truthy values using lodash

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. Eg

_.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?

 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>

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"]

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}

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

Just try

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

_.pickBy(foo, _.identity);

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>

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM