knot22
knot22

Reputation: 2768

refactor code that filters based on value of key/value pairs

I have the following code, which works as expected - it properly filters out key/value pairs with value of null, false and returns an object with the other key/value pairs. However, it's rather verbose and I'm wondering if there's a way to simplify it.

const settings = {
    distance: null,
    length: 23,
    weight: null,
    isActive: false,
    isRound: true
}

const data = {};
Object.entries(settings)
.filter(([, value]) => value !== null)
.filter(([, value]) => value !== false)
.forEach(([key, value]) => (data[key] = value));
      
console.log(data);

Upvotes: 0

Views: 101

Answers (5)

Hanzla Habib
Hanzla Habib

Reputation: 3713

why don't you check these condition in one iteration

change this

.filter(([, value]) => value !== null)
.filter(([, value]) => value !== false)

to

.filter(([, value]) => !!value)

or make use of single loop which checks condition and append data in data object eg:

Object.entries(settings)
      .forEach(([key, value]) => {
        if(!!value) {
          data[key]= value;       
        }
     })

Upvotes: 0

Ana Svitlica
Ana Svitlica

Reputation: 453

You can remove all falsy values and iterate just once:

    const settings = {
        distance: null,
        length: 23,
        weight: null,
        isActive: false,
        isRound: true
    }

    const data = {};
    Object.entries(settings)
      .forEach(([key, value]) => {
        if(!!value) {
          data[key]= value;       
        }
     })
          
    console.log(data);

Upvotes: 6

Aayush Mall
Aayush Mall

Reputation: 1013

In vanilla javscript it would be more easier in a single loop

const settings = {
    distance: null,
    length: 23,
    weight: null,
    isActive: false,
    isRound: true
}

const data = {}

for(var key in settings) {
    if(settings[key] !== false && settings[key] !== null) {
        data[key] = settings[key];
    }
}

Not sure why to use multiple filter methods and reduce as it will cause additional iterations.

Upvotes: 1

TKoL
TKoL

Reputation: 13912

As an alternative, here's a bit of an arguably simpler, but not functional version that uses mutability to delete the offending keys:

const settings = {
    distance: null,
    length: 23,
    weight: null,
    isActive: false,
    isRound: true
}

const copy = Object.assign({}, settings);
Object.entries(copy).forEach(([key, value]) => {
  if (value === null || value === false) delete copy[key];
});

console.log(copy);

A bit shorter, if it's to your taste.

Upvotes: 0

TKoL
TKoL

Reputation: 13912

What about using a reducer instead of your forEach?

const settings = {
    distance: null,
    length: 23,
    weight: null,
    isActive: false,
    isRound: true
}

const data = Object.entries(settings)
  .filter(([, value]) => value !== null && value !== false)
  .reduce((acc, [key, value]) => {
     (acc[key] = value);
     return acc;
  }, {});
      
console.log(data);

Upvotes: 1

Related Questions