Correct terminology in nested for loop - javascript

I'm trying to store all prime numbers of a given number in an array. I'm running an inner loop from 0 to the count of the outer loop every time the outer loop increases by one. I have if statements inside the inner loop to determine if the number is prime.
function sumPrimes(num) {
var primes = [];
for (var i=0; i<num; i++){
for (var j=0; j<num[i]; j++){
if(num[i][j] !== 1){
if(num[i] % num[i][j] !== 0){
primes.push(num[i]);
}
}
}
}
return primes;
}
sumPrimes(10);
Currently this isn't returning anything. What is the correct way of targeting the counters? essentially I want to say - if (the [number of the outer loop count] is NOT divisible by any number bar 1 and itself from the inner loop that leaves no remainder) {
push this step on the outer loop into my 'primes' array
}
Edit: im not seeking better solutions on how to fill up a prime number array of which im sure there is many ill learn after I solve this. I am right now using this problem as an example for nesting for loops and how to correctly call the different parameters.

Related

Javascript Array Diff

I am working on the CodeWars kata Array.diff:
Your goal in this kata is to implement a difference function, which subtracts one list from another and returns the result.
It should remove all values from list a, which are present in list b keeping their order.
arrayDiff([1,2],[1]) == [2]
If a value is present in b, all of its occurrences must be removed from the other:
arrayDiff([1,2,2,2,3],[2]) == [1,3]
My code:
function arrayDiff(a, b) {
for(let i = 0; i<b.length; i++){
for(let j = 0; j<a.length; j++){
if(b[i]===a[j]){
a.splice(j,1)
}
}
}
return a;
}
Somehow, although it works for most arrays, it doesn't give correct results for some arrays. Where exactly am I going wrong?
Using splice on an array which you are iterating is tricky. By removing the current element from that array, the elements that came after it now appear at an index that is one less than where they were before, yet the loop variable will still be increased for the next iteration.
Moreover, this algorithm has a bad time complexity with its double loop over the whole range of indices.
You can do this in linear time: first create a Set so that it only retains unique values as they appear in the second array, and then filter the first array for values that don't appear in that set.
This idea is used in this spoiler:
function array_diff(a, b) {
const remove = new Set(b);
return a.filter( k => !remove.has(k) );
}

Why JavaScript array length return undefined when loop in matrix (2D array) [duplicate]

What is an off-by-one error? If I have one, how do I fix it?
An off-by-one error is for example when you intend to perform a loop n times and write something like:
for (int i = 1; i < n; ++i) { ... }
or:
for (int i = 0; i <= n; ++i) { ... }
In the first case the loop will be executed (n - 1) times and in the second case (n + 1) times, giving the name off-by-one. Other variations are possible but in general the loop is executed one too many or one too few times due to an error in the initial value of the loop variable or in the end condition of the loop.
The loop can be written correctly as:
for (int i = 0; i < n; ++i) { ... }
A for loop is just a special case of a while loop. The same kind of error can be made in while loops.
An off-by-one error is when you expect something to be of value N, but in reality it ends up being N-1 or N+1. For example, you were expecting the program to perform an operation 10 times, but it ends up performing 9 or 11 times (one too few or one too many times). In programming this is most commonly seen happening when dealing with "for" loops.
This error happens due to a misjudgement where you do not realize that the number you are using to keep track of your counting may not be the same as the number of things you are counting. In other words, the number you are using to count may not be the same as the total of things you are counting. There is nothing that obligates both things to be the same. Try to count out loud from 0 to 10 and you end up saying 11 numbers in total, but the final number that you say is 10.
One way to prevent the problem is to realize that our brain has a tendency (maybe a cognitive bias) to make that error. Keeping that in mind may help you identify and prevent future situations. But I guess that the best thing you can do to prevent this error is to write unit tests. The tests will help you make sure that your code is running as it should.
Say you have the following code featuring an array and a for loop:
char exampleArray[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };
for(int i = 0; i <= 11; i++)
{
print(exampleArray[i])
}
See the issue here? Because I counted my array to have eleven characters in it, I have set my loop to iterate eleven times. However, arrays start at zero in most languages, meaning that when my code goes to print
exampleArray[11]
I will get an index out of bounds error because the array in the example has no value at index eleven.
In this case, I can fix this easily by simply telling my loop to iterate one fewer times.
The easiest way to debug this issue is to print out your upper and lower bounds and see which value generates an index out of bounds error, then set your value to be one greater or one fewer than it is throughout your entire iteration.
Of course, this assumes the error is generated by a loop going one over or one less than the bounds of an array, there are other situations where an index out of bounds error can occur, however, this is the most common case. An index out of bounds will always refer to trying to access data where data does not exist due to the boundaries past not being within the boundaries of data.
A common off-by-one confusion arises because some languages enumerate vectors from zero (C, for example) and other languages from one (R, for example). Thus, a vector x of size n has members running from x[0] to x[n-1] in C but from x[1] to x[n] in R.
You are also confronted with the off-by-one challenge when coding the common idiom for cyclic incrementation:
In C:
i = (i+1)%n
In R:
i <- (i-1)%%n + 1
Off by one error (sometimes called OBOE) crop up when you're trying to target a specific index of a string or array (to slice or access a segment), or when looping over the indices of them.
If we consider Javascript as an example language, indexing starts at zero, not one, which means the last index is always one less than the length of the item. If you try to access an index equal to the length, the program may throw an
"index out of range" reference error
or
print undefined.
When you use string or array methods that take index ranges as arguments, it helps to read the documentation of that language and understand if they are inclusive (the item at the given index is part of what's returned) or not. Here are some examples of off by one errors:
let alphabet = "abcdefghijklmnopqrstuvwxyz";
let len = alphabet.length;
for (let i = 0; i <= len; i++) {
// loops one too many times at the end
console.log(alphabet[i]);
}
for (let j = 1; j < len; j++) {
// loops one too few times and misses the first character at index 0
console.log(alphabet[j]);
}
for (let k = 0; k < len; k++) {
// Goldilocks approves - this is just right
console.log(alphabet[k]);
}
A simple rule of thumb:
int i = 0; // if i is initiated as 0, always use a < or > in the condition
while (i < 10)
System.out.printf("%d ", i++);
int i = 1; // if i is initiated as 1, always use a <= or >= in the condition
while (i <= 10)
System.out.printf("%d ". i++);

Question concerning efficiency in calculated array indices and repeated references to a specific array value

In trying to minimize the time it takes a JavaScript function to process, please consider this set up. In the function is a loop that operates on an array of similar objects. The index of the array is [4 + loop counter] and there are several references to array[4+i][various property names], such as a[4+i].x, a[4+i].y, a[4+i].z in each loop iteration.
Is it okay to keep calculating 4+i several times within each loop iteration, or would efficiency be gained by declaring a variable at the top of the loop to hold the value of 4+i and use that variable as the index, or declare a variable to be a reference to the a[4+i] object? Is it more work for the browser to declare a new variable or to add 4+i ten times? Does the browser work each time to find a[n] such that, if one needs to use the object in a[n] multiple times per loop iteration, it would be better to set x = a[n] and just reference x.property_names ten times?
Thank you for considering my very novice question.
Does the browser work each time to find a[n] such that, if one needs to use the object in a[n] multiple times per loop iteration, it would be better to set x = a[n] and just reference x.property_names ten times?
Yes. Although the JavaScript engine may be able to optimize away the repeated a[4+i] work, it also might not be able to, depending on what your code is doing. In contrast, creating a local variable to store the reference in is very, very little work.
Subjectively, it's also probably clearer to the reader and more maintainable to do x = a[4+i] once and then use x.
That said, the best way to know the answer to this question in your specific situation is to do it and see if there's an improvement.
This snippet runs for a bit more than half minutes...
function m(f){
const t=[Date.now()];
const s=[];
for(let r=0;r<10;r++){
s.push(f());
t.push(Date.now());
}
for(let i=0;i<t.length-1;i++)
t[i]=t[i+1]-t[i];
t.pop();
t.sort((a,b)=>a-b);
t.pop();
t.pop();
return t.reduce((a,b)=>a+b);
}
const times=1000;
const bignumber=100000;
const bigarray=new Array(bignumber);
for(let i=0;i<bignumber;i++)
bigarray[i]={x:Math.random(),y:Math.random(),z:Math.random()};
for(let i=0;i<4;i++)
bigarray.push(bigarray[i]);
console.log("idx",m(function(){
let sum=0;
for(let r=0;r<times;r++)
for(let i=0;i<bignumber;i++)
sum+=bigarray[i].x+bigarray[i].y+bigarray[i].z;
return sum;
}));
console.log("idx+4",m(function(){
let sum=0;
for(let r=0;r<times;r++)
for(let i=0;i<bignumber;i++)
sum+=bigarray[i+4].x+bigarray[i+4].y+bigarray[i+4].z;
return sum;
}));
console.log("item",m(function(){
let sum=0;
for(let r=0;r<times;r++)
for(let i=0;i<bignumber;i++){
let item=bigarray[i];
sum+=item.x+item.y+item.z;
}
return sum;
}));
console.log("item+4",m(function(){
let sum=0;
for(let r=0;r<times;r++)
for(let i=0;i<bignumber;i++){
let item=bigarray[i+4];
sum+=item.x+item.y+item.z;
}
return sum;
}));
... and produces output like
idx 2398
idx+4 2788
item 2252
item+4 2303
for me on Chrome. The numbers are runtime in milliseconds of 8 runs (8 best out of 10).
Where
idx is bigarray[b].x+bigarray[b].y+bigarray[b].z, repeated access to the same element with a named index (i)
idx+4 is bigarray[i+4].x+bigarray[i+4].y+bigarray[i+4].z, repeated access to the same element with a calculated index (i+4)
item is item.x+item.y+item.z, so an array element was stored in a variable
item+4 is item.x+item.y+item.z too, just the array element was picked from i+4
Your question is very visibly the outlier here. Repeated access to an element with a "fixed" index (idx case) is already a bit slower than getting out the element into a variable (item and item+4 cases, where +4 is the slower one of course, that addition is executed 800 million times after all). But the 3 times repeated access to an element with a calculated index (idx+4 case) is 15-20+% slower than any of the others.
Here the array is so small that it fits into the L3 cache. If you "move" a couple 0-s from times to bignumber, the overall difference decreases to 10-15%, and anything else than idx+4 performs practically the same.

Why is this code used in many different ways?

I have been going through a tutorial on The Odin Project and I keep coming across this line of code or a variation of the code:
(i = 0; i < fLen; i++)
What exactly is happening here? I don't understand why it is used for multiple programs. If I do not understand what it is doing, then I have a hard time using it.
Example:
var fruits, text, fLen, i;
fruits = ["Banana", "Orange", "Apple", "Mango"];
fLen = fruits.length;
text = "<ul>";
for (i = 0; i < fLen; i++) {
text += "<li>" + fruits[i] + "</li>";
}
In short, it's a For loop that's meant to iterate a set number of times. In that example, it's iterating based up on the length of the array for fruits. So it's going to run 4 times. The i++ at the end just increases the increment after everytime it's run an iteration.
The whole point of that code is that it's creating a unordered list <ul> and then adding the four list items <li> for each index of the fruit array.
It's pretty simple once you get it, there's three pieces to: (i = 0; i < 3; i++)
Start with 0
If i < 3 run the code inside of the braces {}
Add +1 to i
The trick is to realize the code doesn't run when i = 3 since it's no longer < 3.
You can do variations like (i = 3; i > 0; i--) which is the same concept backwards.
Agreed with JohnPete22, it is a for loop, here are some examples:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for
If you are used to some other programming languages, you could consider some alternatives here that might make a little more sense to you:
for in - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
for each - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
while - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while
That's a for loop. It runs the code inside it's block (the { }) multiple times, based on what's inside the parentheses.
The parentheses have three "clauses", separated by semicolons. The first clause is the "initializer", which is only run once at the beginning. The second clause is the "condition", which is checked at the beginning of each time the block is run. If it evaluates to true (or anything "truthy"), the block is run again; otherwise, the loop exits. Finally, the third clause is the "final expression", which is run after the block each time.
Put together, you can make a loop run, say, ten times like so:
for (let i = 0; i < 10; i++) { /* … */ }
This initially sets i to zero, increments i each time, and exits when i hits 10. In your example above, the loop is being used to iterate over each element in the fruits list and collect them into an unordered list.

Total cost function in javascript

i am having issues (very lost) in making a code that me and my friend were given to create.
So I am suppose to compute and return the average of all values in a given array named customerBalance, the array holds the amount of "what customers owe my business" (I dont own a business) and each item in the array holds the "customers balance", i also have to use a for() to process the array and calculate the average and divide by customerBalance length, and finally return the average.
Here is my code so far
function average() {
customerBalance
for(i=0,i++)
sum(customerBalance)
total=sum/5
return average;
I know that this is COMPLETELY wrong, I am not sure on how i start typing the array, please don't be harsh I would really like to know how to do this.
Thank you and have a great day
function average(customerBalance) {
if (customerBalance.length == 0) { // Prevent division by zero later
return 0;
}
var total = 0;
for (var i = 0; i < customerBalance.length; i++) {
total += customerBalance[i];
}
var average = total/customerBalance.length;
return average;
}
You have many problems:
The parameter to a function goes in the parenthese after the function name, not the next line.
Your for() syntax is all wrong. You need to put the initialization, repetition test, and increment separated by semicolons.
There's no sum() function in Javascript. And even if there were, you would need to assign the result to a variable.
When you calculate the average, you're putting it in total, but then you're returning average, which is the variable that contains the function, not the average you calculated.
Other recommendations:
Don't hard-code the array size, use array.length to get it.
Always put braces around the body of for, if, while, etc. even if they're just one line.
Local variables should be declared with var.

Categories