diff --git a/doc/19-library-reference.md b/doc/19-library-reference.md index 99664fb03..83efd8c4e 100644 --- a/doc/19-library-reference.md +++ b/doc/19-library-reference.md @@ -708,8 +708,8 @@ Signature: function reduce(func); Reduces the elements of the array into a single value by calling the provided -function `func` as `func(a, b)` repeatedly where `a` is the previous result of -function call (null initially) and `b` is an element of the array. +function `func` as `func(a, b)` repeatedly where `a` and `b` are elements of the array +or results from previous function calls. ### Array#filter diff --git a/lib/base/array-script.cpp b/lib/base/array-script.cpp index c0482312a..f5924791d 100644 --- a/lib/base/array-script.cpp +++ b/lib/base/array-script.cpp @@ -172,14 +172,17 @@ static Value ArrayReduce(const Function::Ptr& function) if (vframe->Sandboxed && !function->IsSideEffectFree()) BOOST_THROW_EXCEPTION(ScriptError("Reduce function must be side-effect free.")); - Value result; + if (self->GetLength() == 0) + return Empty; + + Value result = self->Get(0); ObjectLock olock(self); - BOOST_FOREACH(const Value& item, self) { + for (size_t i = 1; i < self->GetLength(); i++) { ScriptFrame uframe; std::vector args; args.push_back(result); - args.push_back(item); + args.push_back(self->Get(i)); result = function->Invoke(args); }