Tell us what’s happening:
I am trying to sort out this challenge. My function creates an array with n numbers. What I am trying to do is to filter such array with filter method and a nested for loop. In theory it should filter only those numbers that return true inside the for loop. If I try to run the function passing 10 as argument, the function returns [1,3,5,7,9].
I don’t understand why 9 is filtered.
**Your code so far**
function sumPrimes(num) {
let newArr = Array.from(Array(num).keys());
return newArr.filter(el => {
for (let i = 2; i<num; i++){
return (el%i!=0)
}
})
}
sumPrimes(10);
In my head it should return an array filtered with elements the return module <> 0 for all the for loop iteration. For example 6, is not filtered because the module is 0 when the for loop hit i=3.
I think I got it now. They all stop at i=2? the return made all the iteration stop at i=2. (1,3,5,7,9) return <> 0 at i=2. The iteration stop running for each element.
function sumPrimes(num) {
let newArr = Array.from(Array(num).keys());
return newArr.filter(el => {
for (let i = 2; i < Math.sqrt(num); i++){
if (el % i === 0) return false;
}
return true
})
}
sumPrimes(10);
The problem I got is that in this example when I test the function passing 10 as the argument the three is divided by itself and is considered not prime. Any advise to help me to overcome the stall?
This code makes only a list of primes (again, making and filtering an array is one of the least efficient ways to to this and I strongly recommend you just use a raw loop over the values rather than going through all of the trouble to allocate an array and then filter it!!)
Where are you suming the primes? The name of the function is sumPrimes after all.
FYI, putting a for-loop inside a filter function isn’t usually a good idea. If you have to put a loop inside a filter function like that, that’s a sign you’re doing something wrong. Would highly recommend re-working to get rid of the for-loop. There’s definitely a way to get to a solution that doesn’t have that.
At a high level this is an approach that I would personally take (there are certainly other correct and more efficient ways to go as well):
Create an array consisting of numbers from 1 to “num”
Filter the previous array for all prime numbers
Sum the filtered array
Btw yes I recognize that my step 1 is very inefficient. And on second thought, you don’t need to even do that. I’ll leave it as an exercise what would be efficient.
Don’t make an array. Don’t make an array. Don’t make an array.
It’s the absolute slowest, least efficient solution possible. (Without intentionally trying to make an obscure, slow solution)
I prefer using high order methods like map and filter, but this is a situation where raw loops are fastest and clearest, since JavaScript does not have proper range objects like other high level languages.
Yes, beginners can mix up the filter and regular loop and put those in one place in a wrong way. But in this case, you need some form of loop to determine whether an element is a prime or not.
As to the use of an array and filtering it, I have a mixed feeling, but more toward accepting it if a functional style of coding (map, filter, reduce) is involved. I’m a very old school, remembering the days when a personal computer had something like 64K memory, so I too have aversion toward using an array when it is not necessary. But being familiar with the functional style of coding is so critical in mastering JS frameworks, I think the use (generation) of an array here is acceptable, just for the sake of learning map/filter/reduce. The solution would adapt nicely if we change the question to “Compute the sum of prime numbers in a given array of positive integers.”
Building an array just to be able to loop over the numbers from 2 to n is not functional programming - its just making code slow for no good reason.
JavaScript doesn’t properly support the range objects needed to do this challenge correctly in a functional way. Part of mastering JS is understanding its limitations. Purism in following any coding paradigm - functional, OO, imperative - leads to bad code.
A better way to practice functional, modular code would be to make a prime checking function. That function could be independently refactored and could be incorporated into a loop based solution or a range iterator based solution in a language with proper range support.