测试数组中所有元素是否是一个数的因子 - 在for循环内返回

8
我有以下问题:
编写一个函数,如果数组中的所有整数都是某个数字的因数,则返回true,否则返回false。
我尝试了下面的代码:

function checkFactors(factors, num) {

  for (let i=0; i<factors.length; i++){
    let element = factors[i];
      console.log(element)

    if (num % element !== 0){
      return false 
    }
    else {
      return true
    }
  }
}

console.log(checkFactors([1, 2, 3, 8], 12)) //➞ false

我的解决方案返回了true,这是错误的。我知道是else语句搞砸了它。但我想知道为什么else语句不能放在那里。


2
你应该将 return true 放在循环外面,而将 return false 留在循环里面。原因是,否则你的循环在第一次检查后就会真正停止,返回 true 或 false,而你希望它在发现某个数不是因子时立即返回 false。循环外的 return true 将表示所有提供的数字都是参数的因子。 - Icepickle
2
FYI,不仅仅是你,这是初学编程和循环时人们经常犯的错误之一。 :-) - T.J. Crowder
1
@t.j.crowder,但我们还没有一个好的dupetarget。 - Jonas Wilms
2
@JonasWilms - 是的,我收藏了这个网页,因为它没有太多无关的内容,真的只是早期返回的事情。 :-) - T.J. Crowder
@T.J.Crowder https://dev59.com/fqDha4cB1Zd3GeqP_Szs#42913882是我为此类问题编写的通用重复问题。 - Barmar
7个回答

7
你在一家巧克力店工作,你的老板让你检查所有巧克力(有辣椒巧克力、焦糖巧克力和咖啡巧克力)是否美味。他告诉你以下内容:
“检查所有巧克力,对于每一个巧克力,品尝它,如果没问题,告诉我一切正常,否则告诉我有问题。”¹
你从第一个巧克力开始,它是辣椒巧克力,尝起来很美味,你去告诉老板一切正常。但老板大喊你,因为你还没有尝过焦糖巧克力和咖啡巧克力。
你意识到你的老板实际上要求你做的是:
“检查所有巧克力,对于每个巧克力,品尝它,如果不好吃,立即告诉我,否则继续直到品尝完所有巧克力,然后回到我这里告诉我一切正常。”²
或者用代码表示:
 // ¹
  function checkChocolates(chocolates) {
    for(const chocolate of chocolates) {
       if(isTasty(chocolate)) {
         return true;
       } else {
         return false;
       }
    }
 }

 // ²
 function checkChocolates(chocolates) {
   for(const chocolate of chocolates) {
     if(isTasty(chocolate)) {
       continue; // this could be omitted, as a loop keeps looping nevertheless
     } else {
       return false;
     }
   }
   return true;
 }

由于这在编程中是一项非常常见的任务,因此已经有了更简短的表达方式:

 if(chocolates.every(isTasty)) {
   alert("all chocolates are fine");
 } else {
    alert("Oh, that doesnt taste good");
 }

isTasty 是一个函数,接受巧克力作为输入,并返回 true 或 false。


如果您还没有理解,可以亲自尝试!购买一些巧克力并品尝它!如果有人告诉你“吃巧克力不是学习”,回答“我正在进行 橡皮鸭调试”,那么就没有人能抱怨了 :)


1
一个小问题 - 应该是“巧克力”,而不是“choclate”。 - Wai Ha Lee

5

只需将return true放在for循环之外即可

如果你把 return true 放在 else部分 ,只要有任何一个值不满足 num%element!== 0 ,你的代码就会 return true 。在这种情况下,这是不应该发生的,因为你正在检查数组中所有的值是否都是给定数字的因数。

我们通过第一个例子来理解

  • 对于数组中的第一个元素1,它将检查条件num%element!== 0,结果为false,因此它将进入else条件,并从函数返回 true ,并且不会检查其余的值。
  • 所以你需要在循环结束时保留 return true ,因此只有当循环中的任何一个值不满足if条件时,控制才会转到 return true

function checkFactors(factors, num) {

  for (let i=0; i<factors.length; i++){
    let element = factors[i];
    if (num % element !== 0){
      return false 
    }
  }
  return true
}



console.log(checkFactors([1, 2, 3, 8], 12)) //➞ false
console.log(checkFactors([1, 2], 2))

简而言之——在这种情况下,如果您希望所有条件都匹配作为一个基本规则,可以考虑如下操作:
  1. 将“失败的”返回值保留在for循环中
  2. 将“通过的”返回值保留在函数末尾
对于此类情况,JS内置了Array.every方法。

function checkFactors(factors, num) {
   return factors.every(element => num % element === 0);
}
console.log(checkFactors([1, 2, 3, 8], 12)); 
console.log(checkFactors([1, 2], 2));


1
在循环中,输入的num被测试是否可以被整除,如果num是可整除的,则控制流程将进入else块,从那里函数将返回true
循环没有检查输入数组的所有数字,而是在第一个可整除数字时就返回true
只需使用标志变量来查看所有元素是否都可以被输入数字num整除,如果有任何一个不能被整除,flag将设置为false,然后我们可以break退出循环并将其作为返回值,因为没有必要检查其他数字。

function checkFactors(factors, num) {
  let flag = true;
  for (let i=0; i<factors.length; i++){
    let element = factors[i];
    if (num % element !== 0){
      flag = false;
      break;
    }
  }
  return flag;
}

console.log(checkFactors([1, 2, 3, 8], 12)); 
console.log(checkFactors([1, 2], 2));
console.log(checkFactors([2, 4, 3, 6, 9], 12));
console.log(checkFactors([3, 5, 2, 6, 9], 15));
console.log(checkFactors([4, 2, 8, 1], 16));

你也可以使用Array.every以简明的方式检查相同的内容:

function checkFactors(factors, num) {
   return factors.every(element => num % element === 0);
}
console.log(checkFactors([1, 2, 3, 8], 12)); 
console.log(checkFactors([1, 2], 2));
console.log(checkFactors([2, 4, 3, 6, 9], 12));
console.log(checkFactors([3, 5, 2, 6, 9], 15));
console.log(checkFactors([4, 2, 8, 1], 16));


0
const checkFactors = (factors, num) => factors.reduce((acc, x)=>acc && num%x===0);

或者

const checkFactors = (factors, num) => factors.every(x => num%x===0);

0
            package Map;
            import java.util.ArrayList;
            import java.util.Scanner;

            public class Question3 {
                public void factorize(int number) {
                    ArrayList<Integer> temp = new ArrayList<>();
                    for (int i = 1; i <= number; i++) {
                        if (number % i == 0) {
                            temp.add(i);
                        }
                    }
                }

                public static void main(String[] args) {
                    Scanner sc = new Scanner(System.in);
                    System.out.println("Enter the number do you want to check factorize: ");
                    int i = sc.nextInt();
                    Question3 question3 = new Question3();
                    question3.factorize(i);

                }
            }

0

你的代码逻辑出现了问题。你应该检查数组中的所有元素,如果所有元素都满足条件,就返回 true,但是如果其中一个元素不满足条件,立即返回 false。否则表示有一个项目符合条件,但不是所有元素都符合条件。这就是问题所在。


0
是的,“else”引起了问题。我将其删除并在for循环之外添加了“return true”。
function checkFactors(factors, num) {

  for (let i=0; i<factors.length; i++){
    let element = factors[i];
      console.log(element)

    if (num % element !== 0){
      return false 
    }
  }
  return true;
}

1
虽然他也在寻找解释。 - Icepickle
我看到Icepickle在问题评论中解释得很好! Jonas Wilms的回答也是如此。 - javapedia.net

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接