【问题标题】:How do you do a simple counter in Javascript functional programming?你如何在 Javascript 函数式编程中做一个简单的计数器?
【发布时间】:2018-01-04 05:07:30
【问题描述】:

我正在重做我的编码以更好地适应函数式编程,但我找不到一个没有突变的简单计数器的好解决方案。

const countRows = (element) => (obj) => {
var count = 0;
  Object.entries(obj).forEach(([key,value]) => {
    if (value.nodeName == element) {
      count = count + 1;
    };
  });
  return count;
};

我一直在尝试使用辅助函数和递归来解决这个问题,但除非我使用某种类型的突变,否则似乎没有任何效果。我觉得这应该是非常简单的事情,但我无法理解这应该如何工作。至少我已经将突变包含在函数中,而不是全局变量。

【问题讨论】:

    标签: javascript functional-programming counter


    【解决方案1】:

    这应该可以工作

    Object.keys(obj).filter(key=>obj[key].nodeName == element).length
    

    【讨论】:

    • 这是一个快速的答案,而且效果很好。让我问你,函数式编程中是否有计数器,还是你只需要像刚才那样想一种不同的方法来解决问题?
    • 超级。如果我们有一些特定的条件,我们需要考虑一个,因为我们没有计算所有元素或查找相同的结构。 filter、reduce、forEach 和 map 方法提供了不同的简化方法。
    【解决方案2】:

    公认的解决方案将制作一个 macthes 数组,其唯一目的是对元素进行计数。您可以轻松地制作一个不会发生额外分配的过滤器的计数版本:

    function countIf (coll, predicate, context) {
      return coll.reduce((matches, value) => predicate.call(context, value) ? matches + 1 : matches, 0);
    }
    

    它与高阶函数的下划线兼容并且 它甚至适用于 Backbone 集合。这是我会实施countRows的方法:

    const countRows = (element) => (obj) => 
      countIf(
        Object.keys(obj), 
        value => obj[value].nodeName == element);
    

    【讨论】:

      【解决方案3】:

      我一直在尝试使用辅助函数和递归

      来解决这个问题

      我想给你一个递归解决方案,即使@Orbis已经给你一个很好的解决方案。

      步骤

      • 检查对象是否有条目
        • 对象有条目,检查对象值是否相等,前提是 x
          • 删除第一个对象条目并增加计数器
          • 否则只删除第一个对象条目
      • 否则返回默认为0的计数器

      代码

      “加长”版本

      const isEqualObjectValue = ([key, value], x) =>
        value === x
      
      const countRows = (objectEntries, x, counter = 0) => {
        if (objectEntries.length > 0) {
          if(isEqualObjectValue(objectEntries[0], x)) {
            return countRows(objectEntries.slice(1), x, counter + 1)
          } else {
            return countRows(objectEntries.slice(1), x, counter)
          }
        } else {
          return counter
        }
      }
      
      const test = {
        a: ':o',
        b: 'x',
        c: ':o',
        d: ':o',
        e: 'x'
      }
      
      console.log('how many \':o\' can you find:', countRows(Object.entries(test), ':o'))

      “更短”版本

      const isEqualObjectValue = ([key, value], x) =>
        value === x
      
      const countRows = (objectEntries, x, counter = 0) =>
        objectEntries.length > 0
          ? isEqualObjectValue(objectEntries[0], x)
            ? countRows(objectEntries.slice(1), x, counter + 1)
            : countRows(objectEntries.slice(1), x, counter)
          : counter
      
      const test = {
        a: ':o',
        b: 'x',
        c: ':o',
        d: ':o',
        e: 'x'
      }
      
      console.log('how many \':o\' can you find:', countRows(Object.entries(test), ':o'))

      【讨论】:

        猜你喜欢
        • 2021-08-13
        • 2020-12-18
        • 2017-05-20
        • 2012-09-29
        • 1970-01-01
        • 1970-01-01
        • 2016-08-27
        相关资源
        最近更新 更多