Problem with multiple conditions

Hello, i was doing a Sum All Primes challenge
And wanted to try something opposite of Sieve of Eratosthenes - i would filter out numbers using conditions n % 2 ! = 0, n % 3 != 0, n % 5 != 0, and n % 7 != 0.
However i can’t, for the life of me put any 2 of those conditions together - filter just stops working at all.

Example code(not in a filter, as i was trying different ways to circumvent the issue):

> function sumPrimes(num) {
>   const primeArr = [...Array(num - 1).keys()].map(i => i + 2);
>   for (let i = 0; i < primeArr.length; i++) {
>     switch (true) {
>       case (primeArr[i] == 2):
>         break;
>       case (primeArr[i] % 2 == 0):
>         primeArr.splice(i, 1)
>         break;
>       case (primeArr[i] % 3 == 0):
>         primeArr.splice(i, 1)
>         break;
>     }
>   }
>   return primeArr;
> }
> 
> console.log(sumPrimes(10));

It works fine up until “case (primeArr[i] % 3 == 0)”

Consider what splice is actually doing to the array. How it affects the indices of the numbers from original array?

The way you describe the logic i would filter out numbers, shows way which might be clearer and not be endangered by unexpected side-effects - using the filter method instead.

2 Likes

i forgot about those …
anyway i did try it with filter first - which didn’t work either:

>   const primeArr = [...Array(num - 1).keys()].map(i => i + 2).filter(function (n) {
>     switch (true) {
>       case (n == 2):
>         return n;
>       case (n % 2 != 0):
>         return n;
>     }
>   });

first 2 cases work fine, but as soon as i try putting down another case - filter stops doing anything altogether.,

Remember that callback of the filter function needs to return a truthy value for item that should be kept in array, and falsy value for item that should be filtered out.

1 Like

Doesn’t work. At the end of the loop primes = [ 2 ].
There’s some kind of issue with using multiple remainder as conditions.

Have you made some changes to the original code? If so, please provide the full updated version.

The length of the array is changing when splice is called on it. I think you can make this work the way that you want with minimal changes by decrementing i each time you call splice.

primeArr.splice(i- -, 1);

you also need to add a case for when the value in your array is equal to 3 so it isn’t removed from the array.

1 Like

Don’t use splice. It’s not a good tool when you are iterating over an array.

1 Like

Note, there are way more primes than these 4 so you will need a lot more cases. In general, a list of cases to check sorta defeats the purpose of a prime finding algorithm

1 Like

I ended up following the hint #2 and ‘borrowed’ an algorigthm that looks for primes by multiplication, the rest is a simple reduce.

I know using splice on an array i’m iterating over is no bueno, but i also tried with filter. The code in my second message works fine, but if i try to put another case (n % 3 != 0) -
it immediately stops working altogether

Forgot to add:
Same thing happens even if i leave two remainder conditions, like:

switch (true) {
  case (n % 2 != 0):
    return n;
  case (n % 3 != 0):
    return n;
}

Take for example n == 4, for it to be filtered out, callback function should return falsy value for 4. What would be returned here?

1 Like

I’ve only just now realised what was the problem :fearful:
Anyways the slightly more correct code would be:

function sumPrimes(num) {
//const primeArr = ;
const arr = […Array(num - 1).keys()].map(i => i + 2).filter(function(n) {
if (n === 2 || n === 3 || n === 5 || n === 7 || (n % 2 !== 0 && n % 3 !== 0 && n % 5 !== 0 && n % 7 !== 0)) {
return n;
}
});
return arr.reduce((a, b) => a + b)
}

sumPrimes(10);

Ofcourse, as JeremyLT pointed out it won’t even correctly solve beyond a certain num.

Thanks.

Yeah, you can make an approach with a filter work, though that will be pretty slow, as you end up creating tons of arrays, and creating an array isn’t particularly fast.