1

Is there a way to shorten this if statement in a reduce function. I tried using

acc = [...acc, v || ''];

but that just adds a empty string.

Object.entries(props).reduce((acc, [k, v]) => {
    if (v) {
      acc = [...acc, v];
    }
    return acc;
  }, []);

I also want to not use the k in the [k, v] because linter is freaking out. How to not use the k variable but still get to the value variable ?

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
me-me
  • 5,139
  • 13
  • 50
  • 91

5 Answers5

2

Use a ternary expression. You can use array destructuring to skip the key (k) - [, v]:

Object.entries(props).reduce((acc, [, v]) => v ? [...acc, v] : acc, []);

However, a more functional solution (and since you don't need the key) would be to use Object.values(), and Array.filter() with Boolean to get the same result:

Object.values(props).filter(Boolean);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
1

You could take an empty array as default value and use concat, which resolves the empty array as neutral value.

For getting an item at a known index, you could destructure the array by taking the index.

result = Object
    .entries(props)
    .reduce((acc, { 1: v }) => acc.concat(v || []), []);

A shorter version should be to take only values.

result = Object
    .values(props)
    .reduce((acc, v) => acc.concat(v || []), []);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

I think the simplest way is to use .concat(), like so:

The reason this works is because concat (unlike push) will push the contents of an array to another array, rather than the array reference itself. By concatinating an empty array, it's essentially a no-op if v is falsey. This is the desired functionality, yeah?

var arr = [1,2,3];
var v = null;
var x = 4;
arr = arr.concat(v || []);
console.log(arr);
arr = arr.concat(x || []);
console.log(arr);

In your specific case:

Object.entries(props).reduce((acc, [k, v]) => acc.concat(v || []), []);
mhodges
  • 10,938
  • 2
  • 28
  • 46
0
acc = [...acc, ...(v? [v] : [])]

You could use a combination of the spread syntax like this.

The trick is, that ... on an empty array will do nothing:

 [...[]] --> []

 [1, 2, 3, ...[]] --> [1, 2, 3]
jHilscher
  • 1,810
  • 2
  • 25
  • 29
  • [`...` is not an operator.](https://stackoverflow.com/questions/37151966/what-is-spreadelement-in-ecmascript-documentation-is-it-the-same-as-spread-oper/37152508#37152508) – Felix Kling Feb 08 '19 at 22:17
  • @FelixKling correct, thank's for sharing. MDN lists it as 'spread syntax'. – jHilscher Feb 09 '19 at 19:34
0

You're doing unnecessary operations here: you basically create a new array every loop of reduce, and you're spreading the element of the previous one on top of it, just to add an element at the end! It's basically what the method push does, so you can just use that:

Object.values(props).reduce((acc, v) => (v && acc.push(v), acc), []);
ZER0
  • 24,846
  • 5
  • 51
  • 54