Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/@ember/-internals/runtime/tests/array/reduce-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ class ReduceTests extends AbstractTestCase {
this.assert.equal(res, 6);
}

'@test uses the first item as the initial accumulator when not provided'() {
let obj = this.newObject([1, 2, 3]);
let res = obj.reduce((previousValue, item) => previousValue + item);
this.assert.equal(res, 6);
}

'@test passes index of item to callback'() {
let obj = this.newObject([1, 2, 3]);
let res = obj.reduce((previousValue, item, index) => previousValue + index, 0);
Expand All @@ -19,6 +25,15 @@ class ReduceTests extends AbstractTestCase {
let res = obj.reduce((previousValue, item, index, enumerable) => enumerable, 0);
this.assert.equal(res, obj);
}

'@test throws when called on an empty array without an initial value'() {
let obj = this.newObject([]);

this.assert.throws(
() => obj.reduce(() => 0),
/Reduce of empty array with no initial value/
);
}
}

runArrayTests('reduce', ReduceTests);
25 changes: 19 additions & 6 deletions packages/@ember/array/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1380,19 +1380,32 @@ const EmberArray = Mixin.create(Enumerable, {
return any(this, callback);
},

// FIXME: When called without initialValue, behavior does not match native behavior
reduce<T, V>(
this: EmberArray<T>,
callback: (summation: V, current: T, index: number, arr: EmberArray<T>) => V,
initialValue: V
initialValue?: V
) {
assert('`reduce` expects a function as first argument.', typeof callback === 'function');

let ret = initialValue;
let length = this.length;
let startIndex = 0;
let ret: V;

if (arguments.length > 1) {
ret = initialValue as V;
} else {
if (length === 0) {
throw new TypeError('Reduce of empty array with no initial value');
}

ret = objectAt(this, 0) as unknown as V;
startIndex = 1;
}

this.forEach(function (item, i) {
ret = callback(ret, item, i, this);
}, this);
for (let index = startIndex; index < length; index++) {
let item = objectAt(this, index) as T;
ret = callback(ret, item, index, this);
}

return ret;
},
Expand Down