Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

JavaScript | Imported module breaking inside for loop

I am writing a program which performs Eratosthenes’ Sieve up to a given limit. This is the current code:

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(`, `);

It imports the following module to test whether a number is prime:

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

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

Which in turn imports the following module which provides an array of all factors of a given number:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const factors = [];

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

Both modules have been tested to ensure they work and have been imported properly. The issue is that when isPrime() is called inside the for loop of eratosthenesSieve() it returns false for every iteration, including when prime numbers are passed as the argument.

I am testing eratosthenesSieve() using 30 as the limit as it’s easy to verify the result. The logged output should be the string: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29. Instead it either logs nothing, or in the case of logging primes without .join(), []. After having the loop log ${i}: ${isPrime(i)} on each iteration I realized isPrime() was returning false for every number (i.e logging "0: false" … "30: false"). I tested isPrime() outside of eratosthenesSieve() and inside eratosthenesSieve() but outside the for loop and both times it worked properly.

I thought maybe it was a scope issue, and so I tried using a seperate variable, declared inside eratosthenesSieve() but outside the loop, as the test number instead of i:

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

This had solved a different problem I was having with another program’s loop, though that program didn’t use isPrime(), (I don’t remember what that program’s issue was). However this solution did not work for the Eratosthenes’ Sieve program.

I tried simply logging ${7}: ${isPrime(7)} on every iteration while commenting out the rest of the code inside eratosthenesSive() just to see what would happen. Oddly enough, it logged 7: true on the first iteration (the correct output, obviously), but logged 7: false on every one of the 29 successive iterations.

Finally, I tried refactoring to have the loop start at 1 in case starting at 0 was causing problems. This also did not help.

I am at a loss as to what is going on here and how to fix it. Thank you so much in advance for your help. (My runtime environment is Node.js in VS code on MacOS Sonoma)

>Solution :

You’re modifying the factors array for each call of your isPrime() function without ever resetting it. Because factors is global, the values you push into it persist even after the isPrime()/factorsList() function has finished executing. For example, if you call isPrime(1), then resources.factors updates to be:

[1]

Then on the next iteration, you call isPrime(2), which results in pushing 1 and 2 onto the previous result, now resources.factors will be:

[1, 1, 2]

from here, resources.factors keeps growing, meaning your resources.factors.length === 2 check in isPrime() will never be true.

Instead, make factors local to the factorsList function so that each call to factorsList is independent and returns the factors just for that call:

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

module.exports.factorList = factorList;

Then you can use the returned array in your isPrime function:

const isPrime = (num) => {
  const factors = resources.factorList(num);
  return factors.length === 2;
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading