Как изменить этот код для включения оптимизации хвостового вызова в ES6?
Я написал функцию для рекурсивного суммирования значений, но она не соответствует критериям оптимизации хвостового вызова в ES6 (по причинам, которые я не могу сформулировать).
function sum(...values) {
if(!values.length) {
return 0;
}
return values.shift() + sum(...values);
}
Как я могу изменить его, чтобы иметь право на оптимизацию?
1 ответ
Решение
Вам нужно сделать
return sum(…);
сделать правильный хвостовой вызов. В вашем примере +
операция все еще выполняется после рекурсивного вызова, что делает это неработоспособным.
Типичный подход заключается в использовании вспомогательной функции с параметром аккумулятора:
function sum(...values) {
function sumTo(acc, values) {
if (!values.length) return acc;
else return sumTo(acc+values.shift(), values); // tail-recursive call
}
return sumTo(0, values);
}
Повторяя списки, вы также можете (ab) использовать сам список:
function sum(...values) {
switch (values.length) {
case 0: return 0;
case 1: return values[0];
default: values.unshift(values.shift()+values.shift());
return sum(...values);
}
}
// or alternatively:
function sum(acc, ...values) {
switch (arguments.length) {
case 0: return 0;
case 1: return acc;
default: values[0] += acc;
return sum(...values);
}
}