1
function sumPrimes(num) {
  let nums = Array.from({ length: num + 1 })
    .map((_, i) => i)
    .slice(2);
  for (let n in nums) {
    nums = nums.filter(val => val == nums[n] || val % nums[n] != 0);
  }
  return nums.reduce((prevSum, cur) => prevSum + cur);
}

That is a simple function for adding prime numbers till num. I am new to javascript and this following line really confuses me.

nums = nums.filter(val => val == nums[n] || val % nums[n] != 0)

I know what the filter function does. But I am confused by the statement inside the parentheses. Can someone explain a little bit? Thanks a lot.

  • 2
    Does this answer your question? [What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript?](https://stackoverflow.com/questions/24900875/whats-the-meaning-of-an-arrow-formed-from-equals-greater-than-in-javas) – Ivar Jul 17 '20 at 10:20
  • 2
    What part of it is unclear? In words: *filter `nums`, leaving only those which are equal to `nums[n]` or whose remainder when divided by `nums[n]` isn't zero.* – deceze Jul 17 '20 at 10:21
  • Its just the implementation of this [trial division primality test](https://en.wikipedia.org/wiki/Trial_division) – Kunal Mukherjee Jul 17 '20 at 10:22

4 Answers4

2
nums = nums.filter(val => val == nums[n] || val % nums[n] != 0)
  1. Nums is an Array
  2. A higher Order Function called Filter is getting used on it, you can read more on filter here at mdn https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
  3. if the current value in the iteration which is Val is equal to the nums[n] or it's not divided completely by nums[n] then it will get returned otherwise not.
Ace
  • 1,398
  • 13
  • 24
1

I think the key thing you need to understand is that the line in question must be considered in the context of the for statement that precedes it.

for (let n in nums) {
    nums = nums.filter(val => val == nums[n] || val % nums[n] != 0);
  }

At first glance, it may look like "val == nums[n]" will always be true. Let's see why that is not the case.

There are many things to evaluate every time the filter method's function runs:

a) The contents of nums

b) The value of n

c) The value of nums[n]

d) The value of val

e) The value of "val == nums[n]"

f) The value of "val % nums[n] != 0"

These things need to be evaluated for every call in the .filter function.

Let's see what that looks like during the first call in the filter function. During this first call:

a) The contents of nums is {2,3,4,5,6,7,8,9,10}

b) The value of n is 0

c) The value of nums[n] is nums[0], which is 2

d) The value of val is 2

e) The value of "val == nums[n}]" becomes "2 == 2", which is TRUE

f) The value of "val % num[n] !=0" becomes FALSE

So, this first element will be kept in nums because "val == nums[n}]" is TRUE.

Next, filter will evaluate the above for val = 3 and so on.

Once the filter is through with n=0, it will proceed with the n=1.

Remember that nums is being modified during each run of .filter.

crosen9999
  • 823
  • 7
  • 13
0

nums = nums.filter(val => val == nums[n] || val % nums[n] != 0)

Lets start at the beginning. the line is saying that nums = nums (that value).

You can tell that this line is not the first one where nums is used because the line doesn't begin with var, const, let...

That is why you can use nums when defining it. You are using nums' previous value inside it's new value.

filter() creates an array filled with all array elements that pass a test (provided as a function).

You can read fully about .filter() using the links below.

https://www.w3schools.com/jsref/jsref_filter.asp

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

If the current value in the iteration val => ..., val is either equal to the nums[n] or (which is represented by ||) isn't completely divided by nums[n] so it doesn't equal 0 (this is represented by val % nums[n] != 0) that it will get returned otherwise.

I hope this solves your problem and helps you better understand that line of code!

topsoftwarepro
  • 773
  • 5
  • 19
0
nums = nums.filter(val => val == nums[n] || val % nums[n] != 0)

1. update the value of `nums

reassign the value of nums to a new array which will contain items from the initial value of nums array when the callback of the filter function return true.

nums = nums.filter(val => callback)

2. The callback

val => val == nums[n] || val % nums[n] != 0

the above line is equivalent to

function (val) {
    return val == nums[n] || val % nums[n] !=0;
}

as this line if formed inside of a LOOP

// considere firstly `nums` = [2,4,5,7,8]
let nums = [2,4,5,7,8];


for(let n in nums) {
    nums = nums.filter((val) => {
      console.log(`for n = ${n} ==> .filter is called with val = ${val}`);
      console.log(`So val === nums[n] return ${val == nums[n]}`);
      return val == nums[n] || val % nums[n] != 0;
    });
    console.log(`==================================`);
}

console.log(nums);

I will explain only when the for loop is execute the first time

So let consider

let nums = [2,4,5,7,8];

When the for loop is executed for the first time the variable n which is the index of the FOR LOOP, n = 0 and val = 2 the callback check this line val => val == nums[n] || val % nums[n] != 0 by value it equal to

return 2 == nums[0] || 2 % nums[0] != 0; 

Equal to

return 2 == 2 || 2 % 2 != 0

Or

return true || false != 0 // this return true
Yves Kipondo
  • 5,289
  • 1
  • 18
  • 31
  • Thank you very much for your answer. I am still confusing. Isn't val == nums[n] always true? – Monica White Jul 17 '20 at 11:19
  • No, when the filter is executed, It's some king of loop which is executed for each element in the array. So in the loop the callback to `.filter` will be call respectively when `n` = `0`. with val equal `2`, `4`, `5`, `7`, `8`. With that `val== nums[n]` will be false when the **filter callback** for `n=0` is passed **4**, **5**, **7**, **8**. As It will check `2==4`, `2==5`, `2==7` and `2==8` which will always be false. That is the reason why for **`n=0`** **nums** Array will contains only `2` like this `[2]` – Yves Kipondo Jul 17 '20 at 11:31
  • rerun the above code snippet you'll see how many the filter is call and different value with which it's called – Yves Kipondo Jul 17 '20 at 11:44
  • Can you translate val == nums[n] into human language? What values does the author want to filter out? Thank you. – Monica White Jul 17 '20 at 12:34