【问题标题】:Question about ternary operator within for loop关于for循环内三元运算符的问题
【发布时间】:2019-06-12 18:39:06
【问题描述】:

只是有点好奇为什么 for 循环中带有 if /else 语句的一段代码可以工作,而另一个用三元运算符简化的代码不起作用。

指令是: 定义一个函数 takeWhile,它接受一个回调函数和一个数组作为参数。 takeWhile 将遍历数组,将每个数组元素作为参数传递给回调。每个从回调返回 true 的顺序数组值都应该收集到一个新数组中。只要数组值从回调中返回 false,takeWhile 就应该返回这个新数组。

这段代码运行良好:

const takeWhile = (cb, arr) => {
  // ADD CODE HERE...
  //empty array to push true values into 
  const result = [];
  //for loop
  for(let i in arr){
  //if callback yields true, push to result array.
    if(cb(arr[i])){ 
      result.push(arr[i]);
    // else return result
    } else {
      return result;
    }
  }
  //once loop has concluded, return result
  return result;
};

/*
 * Uncomment the following lines and Run Code to test your work
 */
const isEven = (elem) => (elem % 2 === 0);
console.log(takeWhile(isEven, [2,4,5,6,8])); // -> [2,4]
console.log(takeWhile(isEven, [7, 100, 14])); // -> []
console.log(takeWhile(isEven, [10, 8, 6, 4, 2])); // -> [10, 8, 6, 4, 2]

这段代码使用(我认为)是相同的逻辑,但没有填充结果数组并使用三元运算符正确返回。

const takeWhile = (cb, arr) => {
  //empty array to push true values into 
  const result = [];
  //for loop
  for(let i = 0; i < arr.length; i++){
  //if callback yields true, push to result array, else return result
    return cb(arr[i]) ? result.push(arr[i]) : result;
  } 
  return result;
};

/*
 * Uncomment the following lines and Run Code to test your work
 */
const isEven = (elem) => (elem % 2 === 0);
console.log(takeWhile(isEven, [2,4,5,6,8])); // -> [2,4]
console.log(takeWhile(isEven, [7, 100, 14])); // -> []
console.log(takeWhile(isEven, [10, 8, 6, 4, 2])); // -> [10, 8, 6, 4, 2]

例如

console.log(takeWhile(isEven, [2,4,5,6,8])); // -> [2,4]

返回 1,什么时候应该返回 [2,4]

【问题讨论】:

  • 注意result.push(arr[i]); 分支中没有return。您将无条件返回。

标签: javascript


【解决方案1】:

return cb(arr[i]) ? result.push(arr[i]) : result;

也就是说:如果将当前数组项传递给回调返回一个真值,则在将当前项推送给它之后返回结果数组的长度,否则返回结果数组。

Array.prototype.push 返回数组的长度。并且这里的三元将在第一个循环中返回。

【讨论】:

    【解决方案2】:

    您之前的逻辑是仅在 cb(arr[i]) 错误时才返回。现在你总是在第一次循环迭代后返回。

    同样array.push 返回新数组的长度,而不是新数组。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

    【讨论】:

      【解决方案3】:

      考虑第二个示例的行。

      return cb(arr[i]) ? result.push(arr[i]) : result;
      

      无论条件如何,这都会在第一个循环中结束函数。虽然函数会根据条件返回,但它会在第一次迭代中返回。

      如果三元运算符不包含任何语句,则只能使用它们来代替 if-else 语句。 return 是上面代码中的一条语句。

      这不是被要求的,只是为了提供信息,您可以使用filter() 来获得更简单的代码。

      const getEvens = (arr) => arr.filter(x => x % 2 === 0);
      

      【讨论】:

        【解决方案4】:

        这个条件:

        if(cb(arr[i])){ 
           result.push(arr[i]);
           // else return result
        } else {
           return result;
        }
        

        不等于:

        return cb(arr[i]) ? result.push(arr[i]) : result;
        

        只有当!cb(arr[i]) 无法使用三元运算符时才返回第一个,因为三元运算符的操作数是expressions。而returnstatement。你应该使用if else

        【讨论】:

          【解决方案5】:

          为达到预期效果,修改三元如下

          cb(arr[i]) ? result.push(arr[i]) : i = arr.length;
          
          1. 在 for 循环中删除 return 以执行
          2. result.push(arr[i]) 的返回值是推送的值的长度
          3. 三元的第二个参数将 i 值更改为要停止循环的数组长度

          您的代码中的三元和第一个选项的其他问题,三元没有可用的返回选项,如下所示

           cb(arr[i]) ? result.push(arr[i]) : return result; // invalid syntax but equivalent to option 1 logic which you are trying
          

          请参考此链接 - Why can't we have return in the ternary operator?

          代码示例

          const takeWhile = (cb, arr) => {
            //empty array to push true values into 
            const result = [];
            //for loop
            for(let i = 0; i < arr.length; i++){
            //if callback yields true, push to result array, else return result
              cb(arr[i]) ? result.push(arr[i]) : i = arr.length;
          
            } 
            return result;
          };
          
          /*
           * Uncomment the following lines and Run Code to test your work
           */
          const pushVal = (val) => {
            result.push(arr[i]);
            return result
          }
          const isEven = (elem) => (elem % 2 === 0);
          console.log(takeWhile(isEven, [2,4,5,6,8])); // -> [2,4]
          console.log(takeWhile(isEven, [7, 100, 14])); // -> []
          console.log(takeWhile(isEven, [10, 8, 6, 4, 2])); // -> [10, 8, 6, 4, 2]

          codepen - https://codepen.io/nagasai/pen/xoGOOQ

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-03-29
            • 1970-01-01
            • 2017-08-21
            • 2021-07-18
            • 2011-10-24
            • 2022-01-04
            • 1970-01-01
            相关资源
            最近更新 更多