For computing one value reduce
is what to use. It's really not that special. Imagine you want to sum every element instead.
[1,2,3,4,5].reduce((a,e) => a+e, 0); // => 15
And reduce
you can actually implement with recursion:
Array.prototype.myReduce = function(proc,init) {
var arr = this;
var nLen = this.length;
function helper(acc, nIndex) {
return nIndex >= nLen ?
acc :
helper(proc(acc, arr[nIndex]), nIndex+1);
}
return helper(init, 0);
}
[1,2,3,4,5].myReduce((a,e) => a+e, 0); // => 15
Note that an actual implementation wouldn't have used recursion since JS doesn't optimize tail calls and thus a looping construct would be more effiecent. Eg. Ramda is a functional library that provides means of making programs using compositions, but mapping and reductions in Ramda is implemented with loops.
EDIT
In the event you structure really isn't an array but something like a linked list then you need to check if you are at the end by checking if this is the singleton empty element. Here is an example implementation of a singly linked list with reduce
, which looks thike the previous in this answer except the accessors and stop condition:
function List() {}
List.prototype.cons = function(a) {
var c = new List();
c.a = a;
c.d = this;
return c;
}
List.prototype.car = function() {
return this.a;
}
List.prototype.cdr = function() {
return this.d;
}
List.prototype.reduce = function(proc, init) {
function helper (lst, acc) {
return lst === emptyList ?
acc :
helper(lst.cdr(), proc(acc, lst.car()));
}
return helper(this, init);
}
List.prototype.length = function() {
return this.reduce(acc => acc+1, 0);
}
List.prototype.reverse = function() {
return this.reduce((acc, a) => acc.cons(a),emptyList);
}
// Singleton empty list
window.emptyList = new List();
var example = emptyList.cons(1).cons(2).cons(9);
example.reduce((a,e)=>a+e,0); //=> 12
example.length(); // ==> 3
example.reverse(); // ==> (1,2,9)