Skip to content

Commit

Permalink
#729 -- implementing reduceRight for object iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
jashkenas committed Sep 19, 2012
1 parent 4efca3e commit e769848
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 10 deletions.
10 changes: 5 additions & 5 deletions test/collections.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ $(document).ready(function() {
object = {a: 1, b: 2},
lastKey = _.keys(object).pop();

var expected = lastKey == 'b'
var expected = lastKey == 'a'
? [memo, 1, 'a', object]
: [memo, 2, 'b', object];

Expand All @@ -131,13 +131,13 @@ $(document).ready(function() {

// And again, with numeric keys.

object = {'2': 1, '1': 2};
object = {'2': 'a', '1': 'b'};
lastKey = _.keys(object).pop();
args = null;

expected = lastKey == 'b'
? [memo, 1, '2', object]
: [memo, 2, '1', object];
expected = lastKey == '2'
? [memo, 'a', '2', object]
: [memo, 'b', '1', object];

_.reduceRight(object, function() {
args || (args = _.toArray(arguments));
Expand Down
14 changes: 9 additions & 5 deletions underscore.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,18 @@

// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context, right) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (!right && nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (right) {
index = right.keys[index];
list = right.list;
}
if (!initial) {
memo = value;
initial = true;
Expand All @@ -134,9 +138,9 @@
if (context) iterator = _.bind(iterator, context);
return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
// A right reduce on an object has undefined ordering, so we don't bother.
var reversed = _.isArray(obj) ? obj.reverse() : obj;
return _.reduce(reversed, iterator, memo, context);
var keys = _.keys(obj).reverse();
var values = _.toArray(obj).reverse();
return _.reduce(values, iterator, memo, context, {keys: keys, list: obj});
};

// Return the first value which passes a truth test. Aliased as `detect`.
Expand Down

0 comments on commit e769848

Please sign in to comment.