简体   繁体   English

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

[英]How do you do a simple counter in Javascript functional programming?

I am redoing my coding to better fit functional programming and I can not find a good solution to a simple counter without mutation. 我正在重做编码,以更好地适应函数式编程,但找不到没有突变的简单计数器的好的解决方案。

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

I have been trying to figure it out using a helper function and recursion but nothing seems to be working out unless I use some type of mutation. 我一直在尝试使用辅助函数和递归来解决这个问题,但是除非我使用某种类型的突变,否则似乎没有任何结果。 I feel like this is something that should be super simple but I just cant wrap my head around how this is suppose to work. 我觉得这应该是非常简单的事情,但是我只是无法理解应该如何工作。 At least I have contained the mutation to within the function and not a global variable. 至少我已经将突变包含在函数内,而不是全局变量。

这应该工作

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

The accepted solution will make an array of the macthes for the sole purpose to count the elements. 公认的解决方案将组成一系列数组,仅用于计数元素。 You can easily make a counting version of filter where the extra allocations doesn't happen: 您可以轻松地创建一个没有多余分配的过滤器计数版本:

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

It is compatible with the underscore line of higher order functions AND it even works with Backbone collections. 它与高阶函数的下划线兼容,甚至可以与Backbone集合一起使用。 Here is hwo I would have implemented countRows : 这是我会实现countRows

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

I have been trying to figure it out using a helper function and recursion 我一直在尝试使用辅助函数和递归来弄清楚

I would like to give you a recursive solution , even if @Orbis has already given you a very good solution. 我想给你一个递归的解决方案 ,即使@Orbis已经给你一个很好的解决方案。

Steps 脚步

  • check if object has entries 检查对象是否有条目
    • object has entries, check if object value is equal provided x 对象有条目,检查提供的对象值是否相等x
      • remove first object entry and increment the counter 删除第一个对象条目并增加计数器
      • else remove only the first object entry 否则仅删除第一个对象条目
  • else return the counter which is by default 0 否则返回默认为0的计数器

Code

"Longer" Version “更长的”版本

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

"Shorter" Version “ Shorter”版本

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM