有关for循环内的三元运算符的问题

时间:2019-06-12 18:39:06

标签: javascript

出于某种好奇,为什么在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]

5 个答案:

答案 0 :(得分:1)

您以前的逻辑是仅在cb(arr[i])虚假时返回。现在,您总是在第一次循环迭代之后返回。

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

答案 1 :(得分:1)

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

那是说:如果将当前数组项传递给回调函数将返回真实值,则在将当前项压入该数组后返回结果数组的长度,否则返回结果数组。

Array.prototype.push返回数组的长度。三元组将以任何一种方式在第一个循环上返回。

答案 2 :(得分:0)

考虑第二个示例的行。

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

无论情况如何,这将在第一个循环中结束该功能。尽管函数会根据条件返回,但它将在第一次迭代中返回。

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

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

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

答案 3 :(得分:0)

这种情况:

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])至极时才返回,因为三元运算符的操作数为expressionsreturnstatement。您应该使用if else

答案 4 :(得分:0)

要达到预期效果,请对三元进行如下修改

cb(arr[i]) ? result.push(arr[i]) : i = arr.length;
  1. 使用for循环删除返回以执行
  2. 返回结果。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