你如何在Javascript函数式编程中做一个简单的计数器?

时间:2018-01-04 05:07:31

标签: javascript functional-programming counter

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

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

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

3 个答案:

答案 0 :(得分:2)

这应该有效

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

答案 1 :(得分:2)

接受的解决方案将制作一系列macthes,仅用于计算元素。您可以轻松地创建过滤器的计数版本,其中不会发生额外分配:

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

它与高阶函数AND的下划线兼容 它甚至适用于Backbone集合。这是hwo我将实现countRows

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

答案 2 :(得分:1)

  

我一直在尝试使用辅助函数和递归来判断它

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

的步骤

  • 检查对象是否有条目
    • 对象有条目,检查对象值是否相等,提供x
      • 删除第一个对象条目并递增计数器
      • else仅删除第一个对象条目
  • 否则返回默认为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'))