【问题标题】:Question about returning a boolean from a reducer function关于从 reducer 函数返回布尔值的问题
【发布时间】:2019-06-08 04:29:31
【问题描述】:

我试图弄清楚为什么在我的减速器函数中,当遇到返回 false 的函数时,isTrue 可以从 false 翻转到 true,但不能返回到 false。我只是想了解为什么它可以以一种方式翻转而不能以另一种方式翻转。

我知道翻转发生在return isTrue || val(num);

Directions are "// 定义一个函数 "passOne",它接受两个参数,第一个是任何值,第二个是函数数组。这些函数可以被视为测试,因为它们都将返回 true 或 false。 “passOne”将遍历/循环数组并将值作为参数传递给每个函数。如果至少一个函数(测试)返回true,“passOne”将返回true。如果没有一个函数返回true,“passOne”将返回 false。// 使用您的“passOne”来确定数字 113 是否为负数,偶数,或是否第一个数字为 1。然后测试 213。”

我尝试在 Python Tutor 中将其可视化。

function isNeg(num){
  return num < 0 ? true: false;
}

function isEven(num){
  return num % 2 === 0 ? true : false;
}

function oneDig(num){
  return (num.toString())[0] === `1` ? true : false;
}

const funcs = [oneDig, isNeg, isEven];

// refactor "passOne" so that it uses the built-in "reduce" method instead of a "for" loop

function passOne(num, arr){
  return arr.reduce((isTrue, val) => {
    return isTrue || val(num);
  }, false);
}

console.log(passOne(113, funcs)); //true
console.log(passOne(213, funcs)); //false

代码的行为符合预期,我只是不明白为什么返回“false”的回调不会将 isTrue 翻转回“false”,它如何保持“true”然后不更新为“false”,而不是这就是指令所说的,我只是好奇。

【问题讨论】:

    标签: javascript reduce boolean-expression


    【解决方案1】:

    isTrue 变成true 时,它永远不会再变成false

    因为您使用的是|| 运算符。考虑isTruetrue。那么不管什么回调返回整个值都会true

    console.log(true || false)

    这里实际上不需要reduce(),因为其中一个条件为真,您不需要进一步检查。在这种情况下,您应该使用some()

    const passOne = (num, arr) => arr.some(x => x(num))
    

    如果您想翻转,则意味着您希望代码检查所有条件。然后你需要使用&amp;&amp; 运算符。并将true 而不是false 传递给reduce()

    function isNeg(num){
      return num < 0 ? true: false;
    }
    
    function isEven(num){
      return num % 2 === 0 ? true : false;
    }
    
    function oneDig(num){
      return (num.toString())[1] === `1` ? true : false;
    }
    
    const funcs = [oneDig, isNeg, isEven];
    
    // refactor "passOne" so that it uses the built-in "reduce" method instead of a "for" loop
    
    function passAll(num, arr){
      return arr.reduce((isTrue, val) => {
        return isTrue && val(num);
      }, true);
    }
    
    console.log(passAll(113, funcs)); //false
    console.log(passAll(213, funcs)); //false
    console.log(passAll(-122, funcs)) //true

    或者另一种方法是every()

    const passOne = (num, arr) => arr.every(x => x(num))
    

    【讨论】:

      【解决方案2】:

      对于 113,

      累加器被false 初始化。 所以第一次 isTrue 会是假的。所以它执行val(num)

      如果为假,逻辑或将进入下一个条件,否则不会进入。

      oneDig 是 arr 中的第一项。 oneDig 检查该数字的第一个数字是 1。

      所以对于 113,第一个数字是 1。所以它返回 true。因为 isTrue = true 满足 LogicalOR,所以其他两个 val(num) 之后没有执行。

      对于 213,

      oneDig 返回错误。所以它转到 val(num)

      isNeg 也返回 false。所以它再次进入 val(num)

      最后 isEven 也返回 false。

      就像Array.prototype.some 一样,检查 arr 中的任何函数返回 true,然后最后返回 true,否则检查所有函数,如果没有返回 true,则返回 false

      【讨论】:

        【解决方案3】:

        您可以使用Array#some 而不是Array#reduce 并返回回调结果。

        const
            isNeg = num => num < 0,
            isEven = num => num % 2 === 0,
            oneDig = num => num.toString()[0] === '1',
            funcs = [oneDig, isNeg, isEven],
            passOne = (num, arr) => arr.some(fn => fn(num));
        
        console.log(passOne(113, funcs)); //true
        console.log(passOne(213, funcs)); //false

        【讨论】:

          【解决方案4】:

          我会使用some 来测试数组中的至少一个元素是否通过了提供的函数实现的测试。

          const isNeg = num => num < 0;
          const isEven = num => num % 2 === 0;
          const oneDig = num => (num.toString())[0] === `1`;
          const passOne = (num, arr) => arr.some(fn => fn(num));
          
          const funcs = [oneDig, isNeg, isEven];
          
          console.log(passOne(113, funcs)); //true
          console.log(passOne(213, funcs)); //false
          

          【讨论】:

            猜你喜欢
            • 2013-03-11
            • 1970-01-01
            • 2011-05-09
            • 1970-01-01
            • 2017-06-07
            • 2011-07-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多