0

I have a problem with filtering object's values by true/false, just like in this topic Get object keys for filtered values but without underscore, meaning using exclusively plain JS. There are many more or less similar questions on StackOverflow, but unfortunately I failed to set a working approach.

For example, I have an object:

var anObject = {first_property: false, second_property: true, third_property: false, fourth_property: false, fifth_property: false, sixth_property: true, seventh_property: false, eight_property: nine-nth_property: false}

I need to get a new object, featuring exclusively truthy values, like:

var newObject = { second_property: true, sixth_property: true }

To filter, I wrote the following filter:

function isValid(value) {
    if (typeof value === "undefined" || value == null || value.length == 0 || value == false) {
        return false;
    } else {
        return true;
    }
}

Broke my head and spent a few hours trying different approach, however the result is unsatisfactory. How should I built the algorithm to do this, which custom/out-of-the-box functions is worth using here? Thanks in advance!

2
  • 1
    Please don't reassign Object, at least name the variable object ;-) Commented Aug 2, 2018 at 15:09
  • @Luca OK, renamed it :) Commented Aug 2, 2018 at 15:12

4 Answers 4

4

You need to loop over the key/value pairs and find out which are true. The solution works as follows:

  1. Gets the key/value pairs from the object using Object.entries.
  2. Iterates over the entries using Array.reduce.
  3. In each iteration, checks if value is true. If so, then adds the key/value pair to the result.

var obj = {
  first_property: false,
  second_property: true,
  third_property: false,
  fourth_property: false,
  fifth_property: false,
  sixth_property: true,
  seventh_property: false
};

var res = Object.entries(obj)
  .reduce((result, [key, value]) => {
    if (value) {
      result[key] = value;
    }

    return result;
  }, {})

console.log(res);

Sign up to request clarification or add additional context in comments.

Comments

2

There are a few ways to do this using Object.entries() or Object.keys(), different array methods, etc, but I figured I'd provide one. Filter the keys down to those where the value is true, and then add those keys to the output.

var obj = {
  first_property: false,
  second_property: true,
  third_property: false,
  fourth_property: false,
  fifth_property: false,
  sixth_property: true,
  seventh_property: false
};

var output = {};

Object.keys(obj)                                  //Get all keys from the object ['first_property', 'second_property', ...]
    .filter((key) => obj[key])                    //Filter the list of keys down to only those where their value is true
    .forEach((key) => output[key] = obj[key]);    //For each key in our filtered list, add it to the output object

console.log(output);

4 Comments

Thank you for it! New things popping up for me, will spend today's evening on your and 31piy solutions to grasp the concept.
Glad to have helped. A solution like 31piy's using a single reduce is going to outperform mine, being that mine requires two iterations. That said, I've added some comments to my code so you can get a clearer idea of what some of the code is doing.
Grateful for it! Will get back to this question tomorrow after I grasp the concept and implement the solution successfully
Asking this questions was very useful for me, a great deal of new things that I learned over yesterday's evening, thank you for that. Finally, I successfully implemented the solution proposed by 31piy, as you said, it looks like being the most streamlined approach. Still, thanks to all of you, you complemented my knowledge
2

Also it is possible by reducing Object.keys array (without additional filtering):

Object.keys(obj).reduce((acc, key) => 
  ((obj[key] ? acc[key] = obj[key] : null), acc)
, {});

// {second_property: true, sixth_property: true}

And a bit shorter version:

Object.keys(obj).reduce((acc, key) => (obj[key] && (acc[key] = obj[key]), acc), {});

Comments

1

You can filter (Array.prototype.filter) the truthy keys and create a new object (Array.prototype.reduce) with those:

var obj = {first_property: false,second_property: true,third_property: false,fourth_property: false,fifth_property: false,sixth_property: true,seventh_property: false};    

var result = Object.keys(obj).filter(k => obj[k]).reduce((a,k) => (a[k] = obj[k], a), {});

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.