JavaScript |导入的模块在 for 循环中中断

问题描述 投票:0回答:1

我正在编写一个程序,该程序将埃拉托色尼筛法执行到给定的限制。这是当前的代码:

const { isPrime } = require(`./numPropFuncs.js`);

const limit = 30;
const primes = [];

const eratosthenesSieve = num => {
    for (let i = 0; i <= num; i++) {
        if (isPrime(i)) {
            primes.push(i);
        };
    };
};

eratosthenesSieve(limit);

console.log(primes.join(`, `);

它导入以下模块来测试数字是否为素数:

const resources = require(`./factorList.js`);

const isPrime = num => {
    resources.factorList(num);
    if (resources.factors.length === 2) {
        return true;
    } else {
        return false;
    };
};

依次导入以下模块,该模块提供给定数字的所有因子的数组:

const factors = [];

const factorList = (num) => {
  for (let i = 0; i <= num; i++) {
    if (num % i === 0) {
      factors.push(i);
    };
  };
};

两个模块都经过测试,以确保它们工作并已正确导入。 问题是,当在

isPrime()
的 for 循环内调用
eratosthenesSieve()
时,它会在每次迭代时返回
false
,包括素数时作为参数传递。

我正在测试

eratosthenesSieve()
,使用 30 作为限制,因为这样很容易验证结果。记录的输出应该是字符串:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29
。相反,它要么不记录任何内容,或者在记录
primes
而不记录
.join()
的情况下,[]。每次迭代都有循环日志
${i}: ${isPrime(i)}
后,我意识到
isPrime()
为每个数字返回
false
(即记录“0:假”...“30:假”)。我在
isPrime()
之外和
eratosthenesSieve()
内部测试了
eratosthenesSieve()
,但在 for 循环之外,两次都工作正常。

我认为这可能是一个范围问题,所以我尝试使用一个单独的变量,在

eratosthenesSieve()
内部但在循环外部声明,作为测试编号而不是 i:

const eratosthenesSieve = num => {
    let testNumber = 0;
    for (let i = 0; i <= num; i++) {
        if (isPrime(testNumber)) {
            primes.push(testNumber);
        };
        testNumber++;
    };
};

这解决了我在另一个程序的循环中遇到的另一个问题,尽管该程序没有使用

isPrime()
(我不记得该程序的问题是什么)。然而,这个解决方案不适用于埃拉托色尼筛程序。

我尝试在每次迭代中简单地记录

${7}: ${isPrime(7)}
,同时注释掉
eratosthenesSive()
中的其余代码,只是为了看看会发生什么。奇怪的是,它在第一次迭代时记录了
7: true
(显然是正确的输出),但在 29 个连续迭代中的每一次都记录了
7: false

最后,我尝试重构,让循环从 1 开始,以防从 0 开始导致问题。这也没有帮助。

我不知道这里发生了什么以及如何解决它。预先非常感谢您的帮助。 (我的运行环境是 MacOS Sonoma 上 VS code 中的 Node.js)

javascript loops for-loop module
1个回答
0
投票

您正在为

factors
函数的每次调用修改
isPrime()
数组,而无需重置它。因为它是全局的,所以即使在
isPrime()
/
factorsList()
函数执行完成后,您推入其中的值仍然会保留。例如,如果您调用
isPrime(1)
,则
resources.factors
更新为:

[1]

然后在下一次迭代中,您调用

isPrime(2)
,这会导致将
1
2
推送到上一个结果上,现在
resources.factors
将是:

[1, 1, 2]

从这里开始,

resources.factors
不断增长,这意味着您的
resources.factors.length === 2
签到
isPrime()
永远不会是
true

相反,使

factors
成为
factorsList
函数的本地函数,以便对
factorsList
的每次调用都是独立的,并仅针对该调用返回
factors

const factorList = (num) => {
  const factors = [];
  for (let i = 0; i <= num; i++) {
    if (num % i === 0) {
      factors.push(i);
    }
  }
  return factors;
};

然后您可以在

isPrime
函数中使用返回的数组:

const isPrime = (num) => {
  const factors = resources.factorList(num);
  return factors.length === 2;
};
© www.soinside.com 2019 - 2024. All rights reserved.