简体   繁体   中英

How would I write a recursive function that sums an array of numbers that uses tail call optimization (TCO)?

So I wrote this function that sums an array of numbers using recursion. How would I make this tail call optimized?

function sum(array) {
  if (array.length === 0) {
    return 0;
  } else {
    return array[0] + sum(array.slice(1));
  }
}

sum([1, 2, 3, 4, 5]); // 15

A TCO function needs to return a function call, which replaces the last stack item and prevents the stack to grow.

Therfore you need to store the total as well in the function as parameter and hand over this value at the ent of the recursion.

 function sum(array, total = 0) { if (array.length === 0) { return total; } return sum(array.slice(1), total + array[0]); } console.log(sum([1, 2, 3, 4, 5])); // 15 

Using Array.prototype.reduce() there is no need to do a recursive function:

 const result = [1, 2, 3, 4, 5].reduce((a, c) => a + c, 0); // 15 console.log(result); 

Just use a ternary operator like so:

 const sum = array => array.length ? array[0] + sum(array.slice(1)) : 0; console.log(sum([1, 2, 3, 4, 5])); // 15 

You can also use Array.prototype.reduce to avoid recursion:

 const sum = array => array.reduce((acc, curr) => acc + curr, 0); console.log(sum([1, 2, 3, 4, 5])); 

You can't, tail call optimization (TCO) is not supported in most of browser. You can see support info here .

You can always use for loop. for loop has higher performance in most of situation.

 function getRandomInt(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值} function sum_1(arr) { var s = 0; for (var i = 0; i < arr.length; i++) { s += arr[i]; } return s; } function sum_2(arr){ return arr.reduce((a, c) => a + c, 0); } var arr = []; for (var i = 0; i < 10000000; i++) { arr[i] = getRandomInt(0,100); } let t0 = window.performance.now(); sum_1(arr); // 15 let t1 = window.performance.now(); console.log("sum_1 executed time : " + (t1 - t0) + " ms"); let t2 = window.performance.now(); sum_2(arr); // 15 let t3 = window.performance.now(); console.log("sum_2 executed time : " + (t3 - t2) + " ms"); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM