Javascript Reduce assign and return with implicit return

nook :

I want to remove the keys from my object where the value is equal to null.

I made use of the filter function on Object.entries combined with a reducer.

I managed to create this snippet, but it has a breach: If any key contains a falsey value, the reducer will return the wrong value:

const obj = {
  boolKey: true,
  intKey: 1,
  nullKey: null,
  falseyKey: 0,
  stringKey: 'string',
};

const result = Object.entries(obj)
  .filter(([, value]) => value !== null)
  .reduce((accumulator, [key, value]) => (accumulator[key] = value) && accumulator, {});

console.log(result); // 0

But with this object the result is as expected:

const obj = {
  boolKey: true,
  intKey: 1,
  nullKey: null,
  stringKey: 'string',
};

const result = Object.entries(obj)
  .filter(([, value]) => value !== null)
  .reduce((accumulator, [key, value]) => (accumulator[key] = value) && accumulator, {});

console.log(result);

// { boolKey: true, intKey: 1, stringKey: 'string' }

I know there are other ways to achieve this, but I'd like to know how to make use of the implicit return in the reducer safely.

Nick Parsons :

Your callback function is not returning an object as the accumulator each time it is called. You only return an object when the value you assign is truthy and the current accumulator is an object. For example, when value is 0, value is falsy, so the accumilator[key] = value will return 0. Since the LHS of the && operator is falsy, it will short-circuit, resulting in the falsy value of 0 being returned. One way you could fix this is by using the comma-operator:

const obj = { boolKey: true, intKey: 1, nullKey: null, falseyKey: 0, stringKey: 'string', };

const result = Object.entries(obj)
  .filter(([, value]) => value !== null)
  .reduce((accumulator, [key, value]) => (accumulator[key] = value, accumulator), {});

console.log(result);

Or by reducing to an object by using the spread syntax:

const obj = { boolKey: true, intKey: 1, nullKey: null, falseyKey: 0, stringKey: 'string', };

const result = Object.entries(obj)
  .filter(([, value]) => value !== null)
  .reduce((acc, [key, value]) => ({...acc, [key]: value}), {});

console.log(result);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=220786&siteId=1