guitarfreak
guitarfreak

Reputation: 89

JS - Get object key-value pairs for filtered values WITHOUT underscore

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!

Upvotes: 0

Views: 488

Answers (4)

31piy
31piy

Reputation: 23859

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

Upvotes: 4

dhilt
dhilt

Reputation: 20744

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), {});

Upvotes: 2

Leonid Pyrlia
Leonid Pyrlia

Reputation: 1712

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

Upvotes: 1

Tyler Roper
Tyler Roper

Reputation: 21672

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

Upvotes: 2

Related Questions