Javascript:递归统计数组中所有元素的和?

Javascript: Recursively count the sum of all elements in array?

我正在尝试编写一个递归函数来使用 Javascript 来计算数组中的项目数。

我可以在 Python:

def count(list):
 if list == []:
  return 0
 return 1 + count(list[1:]) 

如何在 ES5 和 ES6 中实现?

首先,你要知道arrays有一个.length property for this purpose. Knowing this, and if you still wants to get it by recursion, I will do something like next, that uses the iterator and Array.slice()。这种方法避免使用 .length 属性 来检测停止条件。

const count = (list) =>
{
    let ite = list[Symbol.iterator]();

    if (ite.next().done)
        return 0;
    else
        return 1 + count(list.slice(1));
}

console.log(count([]));
console.log(count([undefined, null]));
console.log(count([1, 2, undefined, 3, 4]));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

ES6递归函数:

const count = arr => arr[0] == undefined ? 0 : 1 + count(arr.slice(1));
console.log(count([1, 2, 3]));
console.log(count([]));

ES5:

function count(arr) {
  return arr[0] == undefined ? 0 : 1 + count(arr.slice(1));
}
console.log(count([1, 2, 3]));
console.log(count([]));

计数元素是荒谬的,因为你可以只取 length 属性。它将是 O(1) 并按照您的期望进行。至于对元素进行求和或做某事:

// recursively. Works only on arrays 
const sumElements = (arr) => {
  if (arr.length === 1) return arr[0];

  const [e, ...rest] = arr;
  return e + sumElements(rest);
}


// recursively and effiecent. Works only on arrays
const sumElements = (arr) => {
  const helper = (index, acc) => index < 0 ? acc helper(index - 1, acc + arr[index]);
  return helper(arr.length-1, 0);
}


// using higher order functions. Works for all collections that has reduce defined
const sumElements = list => list.reduce((acc, e) => acc + e), 0);

// using iterators. Works for all collections that has iterator defined
const sumElements = (list) => {
  let sum = 0;
  for (const e of list) {
    sum += e;
  }
  return sum;
}

最像 es6 的 fp-ish 写法。适用于所有可迭代对象。

const count = xs =>
  xs[Symbol.iterator]().next().done
    ? 0
    : 1 + (([,...xr]) => count(xr))(xs);

console.log(count([1,2,3]));
console.log(count("hello123"));
console.log(count({
    *[Symbol.iterator]() {
        yield 1;
        yield 2;
        yield 3;
        yield 4;
    }
}));
console.log(count([]));
console.log(count([1, undefined, 2]));

这里有两个解决方案。

const count1 = ([x, ...xs]) => x ? 1 + count1(xs) : 0
const count2 = (xs) => xs.reduce((y) => y + 1, 0)

console.log(count1([1, 2, 3, 4, 5]))
console.log(count2([1, 2, 3, 4, 5]))