【问题标题】:Javascript: Recursively count the sum of all elements in array?Javascript:递归计算数组中所有元素的总和?
【发布时间】:2019-09-26 20:46:06
【问题描述】:

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

我可以用 Python 做到这一点:

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

如何在 ES5 和 ES6 中做到这一点?

【问题讨论】:

  • 是二维数组吗?如果不是,您可以使用 length()。
  • 当你拥有.length 属性时为什么需要这个?另请注意,在 Javascript 上 [] == []false,因此您必须检查 list.length == 0 是否为停止条件。
  • 问题的标题有点令人困惑,我建议您将其编辑为“Javascript:递归计算数组中元素的 number 个?”因为根据正文和代码示例,这就是您要执行的操作。

标签: javascript arrays recursion ecmascript-6 ecmascript-5


【解决方案1】:

首先,您必须知道arrays 有一个.length 属性用于此目的。知道了这一点,如果你仍然想通过递归得到它,我会做类似下一步的事情,使用iteratorArray.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;}

【讨论】:

    【解决方案2】:

    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([]));

    【讨论】:

    • 请注意,关于停止条件与undefined的比较,如果你的输入数组是[1, undefined, 3]呢?
    【解决方案3】:

    计算元素是荒谬的,因为您可以只使用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;
    }
    

    【讨论】:

      【解决方案4】:

      最 es6-ish、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]));

      【讨论】:

      • 请注意,关于停止条件与undefined的比较,如果你的输入数组是[1, undefined, 3]呢?
      • @Shidersz 是的,这是一个错误,感谢您指出。我会更新答案。
      • 是的,我也在考虑这是第一个选项。毕竟,如果输入数据可以保证没有undefined 值,这种情况应该不是问题。
      【解决方案5】:

      这里有两个解决方案。

      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]))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-08
        • 2018-12-10
        • 2021-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多