Javascript 尝试使用reduce查找奇偶数计数

Javascript 尝试使用reduce查找奇偶数计数,javascript,arrays,reduce,higher-order-functions,Javascript,Arrays,Reduce,Higher Order Functions,我试图用reduce解决下面的问题,但是我无法得到对象中奇偶数的正确计数 有人能告诉我我的代码出了什么问题吗 创建一个接受数组和回调的函数countBy,然后 返回一个对象countBy将遍历数组并执行 每个元素上的回调。回调的每个返回值都将 将保存为对象上的关键点。与每个键关联的值 将是返回特定返回值的次数 您正在reduce回调内部将oddCount和evenCount初始化为0,因此在每次迭代中 evenCount++; acc['even'] = evenCount; 仅将evenCo

我试图用reduce解决下面的问题,但是我无法得到对象中奇偶数的正确计数

有人能告诉我我的代码出了什么问题吗

创建一个接受数组和回调的函数
countBy
,然后 返回一个对象
countBy
将遍历数组并执行 每个元素上的回调。回调的每个返回值都将 将保存为对象上的关键点。与每个键关联的值 将是返回特定返回值的次数


您正在
reduce
回调内部将
oddCount
evenCount
初始化为
0
,因此在每次迭代中

evenCount++;
acc['even'] = evenCount;
仅将
evenCount
oddCount
递增到
1
。而是在回调之外初始化计数,以便对它们的更改在
reduce
回调的多个调用中保持不变:

函数计数方式(arr,fn){
让oddCount=0
让evenCount=0
返回arr.reduce(功能(acc、nums){
//控制台日志(nums);
console.log(nums,fn(nums))
如果(fn(nums)=“偶数”){
evenCount++;
acc[‘偶数’]=偶数计数;
}否则{
oddCount++;
acc['odd']=oddCount;
}
返回acc
}, {}, 0)
}
函数奇偶(n){
如果(n%2==0)返回“偶数”;
否则返回“奇数”;
}
var nums=[1,2,3,4,5];

console.log(countBy(nums,偶数));//应该记录:{奇数:3,偶数:2}
正如CertainPerformance所说,您正在重新初始化用于计数的变量。另外,您正在发送一个额外的参数来reduce,这不应该存在。Reduce只需要2个参数

我会这样做的

function countBy(arr, fn) {
  return arr.reduce(function(acc, nums) {
   console.log(nums, fn(nums))
    if(fn(nums) === "even"){
      acc.even ++;
    } else {
      acc.odd ++;
    }
    return acc
  }, {odd: 0, even: 0})
}
根据日志,这是以您想要的方式解决的。如果你按照命令去做,我想它实际上是这样的:

function countBy(arr, fn) {
  return arr.reduce(function(acc, val) {
    let key = fn(val);
    if (!acc[key]) {
      acc[key] = 1;
    } else {
      acc[key]++;
    }
    return acc;
  }, {})
}

您最初的尝试依赖于回调函数返回“奇数”或“偶数”来工作。上述代码可以与返回任何值的函数一起使用,而不是使用数组。reduce也可以通过数组以稍微不同的方式解决此问题。forEach和助手函数:

const isEvenOrOdd=n=>n%2?“偶数”:“奇数”
const propCount=(prop,obj)=>obj[prop]=(obj[prop]| | 0)+1
常量countBy=(arr,fn,obj={})=>{
arr.forEach(x=>propCount(isEvenOrOdd(x),obj))
返回obj
}

log(countBy([1,2,3,4,5],isEvenOrOdd))
我将从一个通用函数开始,该函数用于递增对象
o
上的键
k

const incr=k=>({[k]:val=0,…o})=>
({…o[k]:val+1})
康斯特因克福=
增量(“foo”)
控制台日志
(incrFoo({})
//{foo:1}
,incrFoo({bar:100})
//{bar:100,foo:1}
,incrFoo({foo:3,bar:100})
//{bar:100,foo:4}
,incr(“偶数”)({奇数:2,偶数:2})
//{奇数:2,偶数:3}

)
最简单的方法是创建一个检查偶数的函数,如

const isEven = n => n%2 === 0;
初始化对象结果应该如下所示

{odd: 0, even: 0}
var nums=[1,2,3,4,5];
常数isEven=n=>n%2==0;
const result=nums.reduce((acc,curr)=>{
if(isEven(curr))acc.偶数++;
else acc.odd++;
返回acc;
},{奇数:0,偶数:0})

console.log(结果);//应该记录:{奇数:3,偶数:2}
关于第一个代码段:不,这不是使用
reduce
的方式。如果您这样做,只需使用for…of循环即可。您不需要这些变量,请使用
acc
@SzymonD中的计数器您不需要它们,但OP的代码就是这样做的,因此我将展示如何通过对OP的代码进行最小更改来修复它。当然,最好只检查累加器上的属性,正如您在下面的代码段中所看到的那样。是否还有更多您没有发布的内容?因为从表面上看,我并不认为这是在返回奇数和偶数。我读这篇文章是因为他们需要一个函数来计算给定数组中每个唯一值的出现次数。e、 g.
[1,1,2,4,4,4]
将返回与php类似的
{1:2,2:1,4:3}
{odd: 0, even: 0}