首页 文章

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

提问于
浏览
0

我正在尝试使用reduce来解决下面的问题,但是我无法在对象中获得偶数和奇数的正确计数 .

有人可以指导我的代码有什么问题吗?

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

function countBy(arr, fn) {
  return arr.reduce(function(acc, nums) {
    // console.log(nums);
    let oddCount = 0
    let evenCount = 0
    console.log(nums, fn(nums))
    if(fn(nums) === "even"){
      evenCount++;
      acc['even'] = evenCount;
    } else {
      oddCount++;
      acc['odd'] = oddCount;
    }
    return acc
  }, {}, 0)
}

function evenOdd(n) {
 if (n % 2 === 0) return "even";
 else return "odd";
}

var nums = [1, 2, 3, 4, 5];
console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }

3 回答

  • 0

    除了使用 Array.reduce 之外,您还可以通过 Array.forEach 和辅助函数以稍微不同的方式解决此问题:

    const isEvenOrOdd = n => n % 2 ? "even" : "odd"
    const propCount = (prop, obj) => obj[prop] = (obj[prop] || 0) + 1
    
    const countBy = (arr, fn, obj={}) => {
      arr.forEach(x => propCount(isEvenOrOdd(x), obj))
      return obj
    }
    
    console.log(countBy([1, 2, 3, 4, 5], isEvenOrOdd));
    
  • 1

    你正在 reduce 回调中初始化 oddCountevenCount0 ,所以在每次迭代时,你的

    evenCount++;
    acc['even'] = evenCount;
    

    只是将 evenCountoddCount 递增到 1 . 相反,在回调之外初始化计数,以便对 reduce 回调的多次调用持续更改它们:

    function countBy(arr, fn) {
      let oddCount = 0
      let evenCount = 0
      return arr.reduce(function(acc, nums) {
        // console.log(nums);
        console.log(nums, fn(nums))
        if (fn(nums) === "even") {
          evenCount++;
          acc['even'] = evenCount;
        } else {
          oddCount++;
          acc['odd'] = oddCount;
        }
        return acc
      }, {}, 0)
    
    }
    
    function evenOdd(n) {
      if (n % 2 === 0) return "even";
      else return "odd";
    }
    var nums = [1, 2, 3, 4, 5];
    console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
    

    或者,您可以通过检查累加器上已有属性的值来完全避免外部变量:

    const countBy = (arr, fn) => arr.reduce((acc, num) => {
      const prop = fn(num);
      acc[prop] = (acc[prop] || 0) + 1;
      return acc;
    }, {});
    
    function evenOdd(n) {
      if (n % 2 === 0) return "even";
      else return "odd";
    }
    var nums = [1, 2, 3, 4, 5];
    console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
    
  • 2

    正如CertainPerformance所说,您正在重新初始化您用来计算的变量 . 此外,您正在发送一个额外的参数来减少,这不应该存在 . 减少只需要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(nums);
        if (!acc[key]) {
          acc[key] = 1;
        } else {
          acc[key]++;
        }
        return acc;
      }, {})
    }
    

    您的原始尝试依赖于返回“奇数”或“偶数”的回调函数 . 上面的代码可以使用返回任何值的函数

相关问题