RBF
RBF

Reputation: 13

Lodash _.reduce issue?

I was wondering if anyone could show me what I'm doing wrong here, I'm trying to use _.reduce to get the fields in an object and it seems to be missing the 'first' one every time.

The first line here is plain old js, the next is lodash.

$scope.actualKeys = Object.keys($scope.item);
_.reduce($scope.item, function(result, value, key) {
  $scope.keys.push(key);
});

Where $scope.item is

$scope.item = {
field1: 'test',
field2: 'test',
field3: 'test',
field4: 'test',
field5: 'test',
field6: 'test'
};

https://plnkr.co/edit/J9MBahQNIsZkMFzrHjKG

Upvotes: 1

Views: 561

Answers (4)

aw04
aw04

Reputation: 11177

A reduce function is used to reduce a collection down to a single value. Each time through it accumulates based on the previous value, hence your problem with the first. In other words, while you can make it work (as others have shown), it's the wrong tool for the job.

What you need in this case is a simple loop (or, as you already know, Object.keys).

Upvotes: 0

Carcigenicate
Carcigenicate

Reputation: 45743

If it's missing the first element, I'm going to hazard a guess that since you haven't set an initial accumulator, it's using the first element as the initial accumulator, then starting the fold on the second element.

Note, I don't know lodash; this is just standard reduce behavior. Look up the documention to see how to set an initial accumulator.

Setting an initial accumulator is usually a good idea, unless you know for sure the list will never be empty. Without setting it, trying to reduce an empty list will either throw, or return undefined (depending on the behaviour of lodash). Without accounting for these failures, you may get a surprise down the road.

Upvotes: 1

Kordon
Kordon

Reputation: 254

If you add an accumulator it will work.

$scope.actualKeys = Object.keys($scope.item);
_.reduce($scope.item, function(result, value, key) {
    $scope.keys.push(key);
}, 0);

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 191976

Use _.forEach() instead of _.reduce() (plunk):

_.forEach($scope.item, function(value, key) {
  $scope.keys.push(key);
});

Upvotes: 0

Related Questions